我$watch
要更改对象并设置$scope.changed = true
,但有些情况下,我想在以编程方式更改数据后立即将其设置为false
:< / p>
$scope.$watch('data', function() {
$scope.changed = true;
}, true);
function loadData(data) {
$scope.data = data;
// I want to run $scope.$apply() here so the $watch is triggered
// before changed is set back to false
$scope.$apply();
$scope.changed = false;
}
// in DOM:
<div ng-click="loadData(newData)">
如果我使用非角度事件手动运行loadData
它可以正常工作(当然后来再次$apply
范围),但如果我从上面的{{1}中运行它然后它出现错误,“$ apply has in progress”。
在大多数情况下使用ngClick
可以正常工作,但在某些地方我真的希望它同步发生。
$timeout
是否可以同步应用范围更改,或者我是否更改处理错误?
感谢。
答案 0 :(得分:3)
如果您没有做一些非常特别的事情,可以使用angular.equals
检查两个对象是否相等。将其与angular.copy
结合使用,即可获得原始数据的副本。
$scope.isDirty = function () {
return !angular.equals(initialData, $scope.data);
}
这样做,您无需担心$watch
功能的顺序,代码也会更容易理解。
性能方面,这可能会更重。您可以通过更改来优化它,以便在更改数据时仅更改isDirty。
答案 1 :(得分:0)
ngclick
将占用$apply
处理程序,因此您无法在事件处理函数中运行需要$apply
的进程,只需$timeout
函数中的所有操作:
function loadData(data){
$timeout(function(){
$scope.data = data;
$scope.$apply();
$scope.changed = false;
});
}
试试这个,但没有经过测试......
答案 2 :(得分:0)
您可以使用第二个$scope
变量来跟踪更改是否来自特定功能,并根据该变量启用$scope.changed
中的$watch
变量分配。
添加变量以充当loadData()
功能中的标记。在这种情况下,我们将其称为$scope.explicitChange
:
function loadData(data) {
$scope.data = data;
// I want to run $scope.$apply() here so the $watch is triggered
// before changed is set back to false
$scope.$apply();
$scope.changed = false;
$scope.explicitChange = true;
}
检查$scope.explicitChange
中是否设置了$watch
:
$scope.$watch('data', function(){
if(!$scope.explicitChange){
$scope.changed = true;
}
else{
// Reset $scope.explicitChange
$scope.explicitChange = false;
}
}, true);