如何在AngularJS中跟踪$ watch模型更新的来源?

时间:2013-12-28 00:05:26

标签: javascript angularjs angularjs-scope

在我的多用户AngularJS应用程序中,我的范围内有一个模型对象。用户输入和服务器更新可以操纵此模型。

我有一个$ watch观察员来跟踪模型并更新UI。是否可以从我的$ watch函数中确定我的模型更新的来源/原因?如果没有这个检查,我就会遇到反馈循环问题(例如UI→服务器→用户界面)。

更新一些代码

控制器:

$scope.elementProperties = { left: 0 };

$scope.$watch('elementProperties.left', function(newVal, oldVal) { changeSelectedElementProperty('left', newVal, oldVal); } );

指令:

angular.module('myapp.ui-editor').directive('myappPropertiesPanel', function () {
    return {
        templateUrl: 'views/ui-editor/myappPropertiesPanel.html',
        restrict: 'A',
        scope: { elementProperties: '=' },

        link: function postLink (scope, element, attrs) {
            scope.$watch('elementProperties.left', function(newVal, oldVal) { console.log('PropertiesPanel change left', newVal, oldVal); } );
        }
    };
});

3 个答案:

答案 0 :(得分:0)

实现此目标的一种方法是使用事件而不是$watch

请参阅working plunker here

在我的plunker中,我添加了$interval,它将通过每隔几秒更改一次值来模拟Web服务调用。

这是你可以做的。

在http调用的then处理程序中,在将从Web服务检索的新值设置为模型之前,使用包含旧值和新值的有效负载发布事件,如下所示:

$http.get('url goes here')
 .then(function (response) {
     scope.$broadcast('UPDATE_FROM_SERVER',
                      {oldValue: scope.elementProperties.left, newValue: response.data.left});
     scope.elementProperties.left = response.data.left;
  };

然后,在您的表单控件中,用户将更改值,请附加ng-click,如下所示:

ng-change="userChangeHandler(elementProperties.left, '{{elementProperties.left}}')

请注意'{{elementProperties.left}}'周围的引号。这将确保更改处理函数将获取属性的旧值。

现在,您可以收听如下所示的变更事件:

  $scope.$on('UPDATE_FROM_SERVER', function (event, changes) {
    // This code will be invoked when the data is changed by the server
    $scope.messages.push('Data changed by Server from ' + changes.oldValue + ' to ' + changes.newValue);
  });

  $scope.$on('UPDATE_FROM_USER', function (event, changes) {
    // This code will be invoked when the data is changed by the user
    $scope.messages.push('Data changed by User from ' + changes.oldValue + ' to ' + changes.newValue);
  });

答案 1 :(得分:0)

“是否可以从$ watch函数中确定模型更新的来源/原因?”

简短的回答是“否”,因为当观察者测试oldWatchedValue === newWatchedValue并发现它时,未在更改时标记更改,而是在以下摘要中,所以无法知道更改的来源未通过相等性检查。因此,没有任何约束可以约束变更源的事实。

答案 2 :(得分:-1)

您应该尝试解耦​​用户输入和服务器更新时发生的逻辑。

这样做的一种方法是让$ watch始终更新UI模型。在IU方面,使用ng-model和ng-change。例如。

<input ng-model="myModel" ng-change="watchMyModel(myModel)">

这样,当您点击$ scope.watchMyModel函数时,您将知道更改来自后端。