我深深地看着一个绑定多个控件的属性:
$scope.$watch('config', function(){}, true);
配置本身包含各种参数:
我想忽略特定控件和特定功能更改 scale 时的更改。
有没有办法忽略特定属性或覆盖手表是特定情况?
目前这就是我正在做的事情:
dataChange现在仅在某些更改时触发,在这种情况下,当其他属性时, 不缩放正在改变。
为了禁用特定缩放案例的dataChange,我只是将其分配给其他案例。
我使用Switch而不是if / else只是因为它更具描述性,并且可以在更多情况下轻松扩展。
$scope.$watch('config', function(n,o,scope){
$scope.config = n;
if (n != o) {
switch(true){
case n.zoom != o.zoom:
break;
default:
$scope.dataChange($scope.dataTable);
};
}
}, true);
答案 0 :(得分:7)
我不喜欢这些答案。 $ watch的第一个参数是要观察的内容,它接受属性名称作为字符串,或者接受返回值的函数。只需使用功能&返回您要观看的值。在这里,我使用lodash JS库来观察一个基于真实对象的新对象,但是剥离了属性:
$scope.$watch(function() {
return _.omit($scope.config, 'scale');
}, function(oldVal, newVal) {
console.log(oldVal, newVal);
});
没有Lodash [黑名单属性]:
$scope.$watch(function() {
var myConfig = Angular.copy(config);
delete myConfig.scale;
return myConfig;
}, function(oldVal, newVal) {
console.log(oldVal, newVal);
});
没有Lodash [白名单属性]:
$scope.$watch(function() {
return {
point: $scope.config.point,
aggregates: $scope.config.aggregates,
current: $scope.config.current
};
}, function(oldVal, newVal) {
console.log(oldVal, newVal);
});
在我看来,其他答案不是“Angular方式”。这种方法不仅比其他凌乱的答案更简洁,而且还避免在$ watch触发时执行冗余对象比较。请记住,其他答案会产生两次对象比较的成本,一次是Angular代码中的$ watch本身,那么您将在回调函数中产生“自制”对象比较的成本。我的方法确保只在Angular代码中进行一次对象比较,方法是在将对象送入$ watch进行比较之前剥离不需要的属性。
答案 1 :(得分:2)
据我所知,但是一个简单的检查可以解决问题:
$scope.$watch('config', function(newValue, oldValue){
if (newValue.scale == oldValue.scale) {
// ignore this
return;
}
// continue...
}, true);
答案 2 :(得分:0)
更好的解决方案可以是该功能;
$scope.equalsAdvanced=function (sourceObject, targetObject, ignoredProperties)
{
// direct compare if there is no ignored properties
if (!ignoredProperties || (angular.isArray(ignoredProperties) && ignoredProperties.length<=0)) {
return angular.equals(sourceObject, targetObject);
}
// take the original ignored property list to a new variable
var ignoredPropertyList=ignoredProperties;
// make it array if it is not
if (!angular.isArray(ignoredPropertyList)) {
var list = [];
list.push(ignoredPropertyList);
ignoredPropertyList = list;
}
// compare property list
for (propertyName in sourceObject) {
if (ignoredPropertyList.indexOf(propertyName) >= 0)
continue;
var sourceValue = sourceObject[propertyName];
var targeValue = targetObject[propertyName];
if (!angular.equals(sourceValue, targeValue))
return false;
}
return true;
};
您可以查看小提琴上的示例代码: http://jsfiddle.net/tursoft/DpEwV/4/
这可能比以前更好;
CODE:
// service
myApp
.service("utils", function()
{
self=this;
// watchAdvanced =====================
self.$watchAdvanced = function ($scope, exp, ignoredProperties, callback)
{
$scope.$watch(exp, function (newValue, oldValue) {
if (self.equalsAdvanced(newValue, oldValue, ignoredProperties))
return;
callback(newValue, oldValue);
}, true);
}
// equalsAdvanced =====================
self.equalsAdvanced=function (sourceObject, targetObject, ignoredProperties)
{
// direct compare if there is no ignored properties
if (!ignoredProperties || (angular.isArray(ignoredProperties) && ignoredProperties.length<=0)) {
return angular.equals(sourceObject, targetObject);
}
// take the original ignored property list to a new variable
var ignoredPropertyList=ignoredProperties;
// make it array if it is not
if (!angular.isArray(ignoredPropertyList)) {
var list = [];
list.push(ignoredPropertyList);
ignoredPropertyList = list;
}
// compare property list
for (propertyName in sourceObject) {
if (ignoredPropertyList.indexOf(propertyName) >= 0)
continue;
var sourceValue = sourceObject[propertyName];
var targeValue = targetObject[propertyName];
if (!angular.equals(sourceValue, targeValue))
return false;
}
return true;
};
});
用法:
utils.$watchAdvanced($scope, "user", ["_State", "ID"], function(newValue, oldValue)
{
$scope.changeCount+=1;
$scope.logs.push($scope.changeCount + ": User object is changed!");
}, true);