当reloadOnSearch为false时,$ location.search上的AngularJs $ watch不起作用
我的routeProvider路由有reloadOnSearch设置为false :
$routeProvider .when( "/film/list", { templateUrl: '/film/list.html', controller: FilmListController, reloadOnSearch: false } .... )
我这样做是因为我不希望整个控制器在查询string更改后重新加载,但我仍然使用它,并且URL如下所示: film/list?sort=isbn&order=asc&offset=0
。 现在每当查询string更改,我想从我的控制器调用一个函数。 所以我试图在控制器中设置$ watch :
$scope.location = $location; $scope.$watch( 'location.search()', function( search) { $scope.list(); });
但是这不起作用。 如果我将$ watch设置为查看查询string的单个参数的更改,那么它将起作用。 但是我不想为我的查询string的每个参数设置$ watch。 我现在使用的解决scheme是这样的:
$scope.location = $location; $scope.$watch( 'location.url()', function( url ) { if($location.path() == '/film/list') $scope.list(); });
因此,我没有注意search,而是观察整个url,然后检查path是否是我在routeProvider中设置的path,以有条件地调用该函数。 我不喜欢这个解决scheme是我必须明确键入$ location.path的值来匹配。
任何人都可以提出一个更好的解决scheme,也许可以解释为什么$ watch不工作$ location.search() ?
您可以在您的控制器中侦听$routeUpdate
事件:
$scope.$on('$routeUpdate', function(){ $scope.sort = $location.search().sort; $scope.order = $location.search().order; $scope.offset = $location.search().offset; });
如果你不使用Angular的路由分辨率,或者你只是想知道$ location的位置发生变化,那么只是为了这个目的
$rootScope.$on('$locationChangeSuccess', function(event){ var url = $location.url(), params = $location.search(); })
Stewies的回答是正确的,你应该听取$routeUpdate
事件,因为它更有效率。
但要回答你的手表为什么不工作, 当你观看location.search()
,你正在观察search方法返回的引用是否相同。 每当你调用它时,它都会返回同一个对象的引用,这就是为什么你的手表没有被触发。 也就是说,即使search参数发生变化,仍然是返回的对象。 为了解决这个问题,你可以把第三个参数传给$watch
。 这将告诉Angular通过价值进行比较,而不是参考。 但是在创build这样的手表时要小心,因为它们会消耗更多的内存,并且需要更长的时间来执行。 所以这就是为什么你应该像stewie说的那样做。
使用
$scope.$watch(function(){ return $location.search() }, function(params){ console.log(params); });
代替。
在控制器上routeUpdate
的更改,如下所示:
$scope.$watch('$routeUpdate', function(){ $scope.sort = $location.search().sort; $scope.order = $location.search().order; });