【问题标题】:AngularJs $watch on $location.search doesn't work when reloadOnSearch is false当 reloadOnSearch 为 false 时,$location.search 上的 AngularJs $watch 不起作用
【发布时间】:2013-02-12 04:29:39
【问题描述】:

我的 routeProvider 路由的 reloadOnSearch 设置为 false

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

  )

我这样做是因为我不希望在查询字符串更改后重新加载整个控制器,但我仍然使用它并且 url 看起来像这样: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();
 });

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

谁能提出一个更好的解决方案,或许可以解释一下为什么 $watch$location.search() 不起作用?

【问题讨论】:

标签: angularjs listener watch


【解决方案1】:

如果你不使用 Angular 的路由解析,或者你只是想知道 $location 何时发生变化,那么有一个事件就是为了这个目的

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

【讨论】:

  • 这是完美的答案。它解决了我的问题。有没有像 $locationChangeSuccess 这样的全局变量列表?
  • @RakeshBurbure 你可以查看源代码:) 它可以帮助:)
【解决方案2】:

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

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

【讨论】:

  • 只是想指出,您必须在路线上将 reloadOnSearch 设置为 false 才能使 $routeUpdate 可用。我通过谷歌找到了这个答案,我花了很长时间才弄清楚为什么 $routeUpdate 一开始不可用。 (它在文档中,我只是错过了)。
【解决方案3】:

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

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

【讨论】:

  • 太好了,这解释得真好!如果您不介意,因为他早些时候发布了答案,我会接受斯图伊的回答,尽管这种解释使答案变得完整。
  • 建议使用 $watch (objectEquality) 的第三个参数是一个很好的提示。参见stackoverflow.com/questions/14867772/… 以及
  • 很好的解释。
【解决方案4】:

使用

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

改为。

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      watchExpression => 应该是

      1. 作为表达式计算的字符串或
      2. 以当前作用域为参数调用的函数

      所以在这里,您应该将第一个参数作为函数传递。

      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); }
                         ) ;
      

      这确实对我有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-25
        • 2016-05-08
        • 1970-01-01
        • 2015-01-31
        • 2021-04-16
        • 2013-03-17
        • 1970-01-01
        相关资源
        最近更新 更多