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

Posted

技术标签:

【中文标题】当 reloadOnSearch 为 false 时,$location.search 上的 AngularJs $watch 不起作用【英文标题】:AngularJs $watch on $location.search doesn't work when reloadOnSearch is false 【发布时间】: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() 不起作用?

【问题讨论】:

尝试将 location.search() 包装在一个函数中。请参阅***.com/questions/13465690/… 了解更多信息。 进行深度观察。将 true 作为 3. 参数添加到手表。 AngularJS Search Change Event的可能重复 【参考方案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) 的第三个参数是一个很好的提示。参见***.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 => 应该是

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

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

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

这确实对我有用。

【讨论】:

以上是关于当 reloadOnSearch 为 false 时,$location.search 上的 AngularJs $watch 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 具有相同模板的多个路由不应重新渲染

当其中一个变量为 False 时 (&&) 不返回 False [关闭]

当 ShowsPlaybackControls 为 False 时,AVPlayerViewController 不会自动旋转视频

为啥当 Debug 设置为 False 时,Django 会为静态媒体生成 HTTP 500 错误?

当命令 CanExecute 为 false 时,按钮不会被禁用

当背景选项为 False 时启用在引导模式外部单击