在我的多用户AngularJS应用程序中,我的作用域上有一个模型对象。这个模型可以通过用户输入和服务器更新来操作。
我有一个$watch观察器来跟踪模型并更新UI。是否可以从我的$watch函数中确定我的模型更新的来源/原因?如果没有检查,我在反馈循环(例如UI→服务器→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); } );
}
};
});
实现这一点的一种方法是使用事件而不是$watch
在此处查看工作 plunker
在我的 plunker 中,我放入了一个$interval
,它将通过每隔几秒钟更改一次值来模拟 Web 服务调用。
这是你能做的。
在超文本传输协议调用的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;
};
然后,在用户将更改值的表单控件中,附加一个如下所示的< code>ng-click:
ng-change="userChangeHandler(elementProperties.left, '{{elementProperties.left}}')
请注意< code >“{ { element properties . 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);
});
“是否可以从我的$watch函数中确定我的模型更新的来源/原因?”
简而言之,答案是否定的,不可能知道更改的来源,因为更改时没有标记更改,而是在观察程序测试oldWatchedValue===newWatchedValue并发现它未通过相等性检查时根据以下摘要进行标记。因此,没有任何约束更改来源发生更改的事实。
您应该尝试分离用户输入和服务器更新时发生的逻辑。
可以做到这一点的一种方法是让$watch始终更新UI模型。在IU方面,使用ng模型和ng变化。例如。
<input ng-model="myModel" ng-change="watchMyModel(myModel)">
这样,当您点击$range. watchMyModel函数时,您将知道更改来自后端。