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

时间:2013-02-26 16:13:10

标签: angularjs listener watch

路径的 routeProvider reloadOnSearch 设置为 false

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

  )

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

$scope.location = $location;
$scope.$watch( 'location.search()', function( search) {
        $scope.list();
 });

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

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

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

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

6 个答案:

答案 0 :(得分:105)

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

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

答案 1 :(得分:77)

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

$scope.$on('$routeUpdate', function(){
  $scope.sort = $location.search().sort;
  $scope.order = $location.search().order;
  $scope.offset = $location.search().offset;
});

答案 2 :(得分:26)

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

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

答案 3 :(得分:10)

使用

$scope.$watch(function(){ return $location.search() }, function(params){
    console.log(params);
});

代替。

答案 4 :(得分:1)

在控制器中观察routeUpdate这样的变化:

 $scope.$watch('$routeUpdate', function(){
     $scope.sort = $location.search().sort;
     $scope.order = $location.search().order; 
 });

答案 5 :(得分:1)

$ watch(watchExpression,listener,[objectEquality]);

watchExpression =>应该是

  1. 评估为表达式或
  2. 的字符串
  3. 使用当前范围作为参数调用的函数
  4. 所以在这里,您应该将第一个参数作为函数传递。

    JavaScript示例=>

    $scope.$watch (
                    function () { return $scope.$location.search(); };
                    function (value) { console.log(value); } 
                  );
    

    打字稿示例=>

    this.$scope.$watch (
                         () => { return this.$location.search(); },
                         (value: any) => { console.log(value); }
                       ) ;
    

    这对我有用。