当reloadOnSearch为false时,AngularJs $ watch on $ location.search不起作用

MBo*_*zic 46 listener watch angularjs

我的routeProvider for route将reloadOnSearch设置为false:

 $routeProvider
     .when(
        "/film/list",
         {
          templateUrl: '/film/list.html', 
          controller: FilmListController,
          reloadOnSearch: false
          } 
          ....

  )
Run Code Online (Sandbox Code Playgroud)

我这样做是因为我不希望在查询字符串更改后重新加载整个控制器,但我仍然使用它,并且url看起来像这样:film/list?sort=isbn&order=asc&offset=0.现在每当查询字符串更改时,我想从我的控制器调用一个函数.所以我试着在控制器中设置$ watch:

$scope.location = $location;
$scope.$watch( 'location.search()', function( search) {
        $scope.list();
 });
Run Code Online (Sandbox Code Playgroud)

但这不起作用.如果我设置$ watch来查看查询字符串的单个参数的更改,那么它可以工作.但我不想为查询字符串的每个参数设置$ watch.我现在使用的解决方案是:

$scope.location = $location;
$scope.$watch( 'location.url()', function( url ) {
    if($location.path() == '/film/list')
        $scope.list();
 });
Run Code Online (Sandbox Code Playgroud)

因此,我不是观察搜索,而是观察整个网址,然后检查路径是否是我在routeProvider中设置的路径,以有条件地调用该函数.我不喜欢这个解决方案是我必须明确键入要匹配的$ location.path的值.

任何人都可以建议一个更好的解决方案,也许可以解释为什么$ watch不适用于$ location.search()

Le *_*Duy 107

如果您不使用Angular的路由解析,或者您只是想知道每当$ location更改时,就会出现一个仅用于此目的的事件

$rootScope.$on('$locationChangeSuccess', function(event){
        var url = $location.url(),
            params = $location.search();
})
Run Code Online (Sandbox Code Playgroud)


Ste*_*wie 77

您可以$routeUpdate在控制器中侦听事件:

$scope.$on('$routeUpdate', function(){
  $scope.sort = $location.search().sort;
  $scope.order = $location.search().order;
  $scope.offset = $location.search().offset;
});
Run Code Online (Sandbox Code Playgroud)

  • 只是想指出你必须在路由上将reloadOnSearch设置为false以使$ routeUpdate可用.我通过谷歌找到了这个答案,我花了很长时间才弄清楚为什么$ routeUpdate最初没有.(它是在文档中,我只是错过了它). (29认同)

And*_*ahl 26

Stewies的答案是正确的,你应该听取$routeUpdate事件,因为它更有效率.

但要回答为什么你的手表不工作; 当你观看时location.search(),你正在观察搜索方法返回的引用是否相同.并且每次调用它时它都会返回对同一对象的引用,这就是为什么你的手表没有发射的原因.也就是说,即使搜索参数发生变化,它仍然是返回的同一对象.为了解决这个问题,你可以传入true作为第三个参数$watch.这将告诉Angular按值而不是参考进行比较.但是在创建这样的手表时要小心,因为它们会消耗更多的内存,并且需要更长的时间来执行.这就是为什么你应该这样做,就像stewie说的那样.


Tho*_*aux 10

使用

$scope.$watch(function(){ return $location.search() }, function(params){
    console.log(params);
});
Run Code Online (Sandbox Code Playgroud)

代替.