【问题标题】:$rootScope.$watch triggered twice$rootScope.$watch 触发了两次
【发布时间】:2015-05-20 17:31:41
【问题描述】:

我想在变量newChat 像这样更改后触发一个新的聊天:

$rootScope.newChat = {
  roomId: roomId,
  friendId: friendId
};

在我的ChatController$watch 中的变量是这样的:

$rootScope.$watch('newChat', function (data) { /*do stuff*/ }

第一次重新加载页面后,这在我的页面上有效,没有任何问题。但是对于第一次加载,$watch 会被触发两次,这会导致聊天的其他部分出现问题。

我检查了newChat 的值。两次的值完全相同。我的应用程序的其他部分没有使用 $rootScope.newChat 变量

为什么会这样,我该如何解决?

【问题讨论】:

  • 观察者注册到作用域后,会异步调用监听器fn(通过$evalAsync)来初始化观察者。在极少数情况下,这是不可取的,因为当 watchExpression 的结果没有改变时调用了侦听器。要在侦听器 fn 中检测这种情况,您可以比较 newVal 和 oldVal。如果这两个值相同 (===),则由于初始化而调用了侦听器。
  • 详细了解参数是什么
  • 问题在于newValoldVal 的两种执行情况完全相同。我只是仔细检查了它
  • 或者只是像在这个答案中那样抑制第一个事件:stackoverflow.com/a/16950610/4910019
  • 它不会改变任何东西,因为它会同时触发两次

标签: javascript angularjs watch


【解决方案1】:

每个手表都会在 $digest 循环运行时触发。您需要做的是检查新值与旧值。

$rootScope.$watch('newChat', function (newValue, oldValue) {
    if(newValue !== oldValue){
        /*do stuff*/
    }
});

【讨论】:

  • 问题在于newValoldVal 的两种执行情况完全相同。我只是仔细检查了它
  • 是的,我也面临同样的问题。如果值相同,我添加了一个返回条件,但是......它会触发两次。
【解决方案2】:

我这样解决了这个问题

$rootScope.$watch('someValue', function (){
                /* rewrite into a new scope */
                $scope.someValue = $rootScope.someValue;
            });
 $scope.$watch('someValue', function (){/*To do*/});

【讨论】:

    猜你喜欢
    • 2019-04-03
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多