AngularJS忽略被监视对象中的键,或者重写$watch监听器
AngularJS ignoring a key in an watched object or overriding the $watch listener
我正在深入观察一个绑定到多个控件的属性:
$scope.$watch('config', function(){}, true);
配置本身包含各种参数:
- 骨料 目前
当缩放被特定控件和特定函数更改时,我想忽略对的更改。
是否有一种方法可以忽略特定的属性或覆盖手表的特定情况?
现在我正在做的是:
datachchange现在只在某些更改时触发,在这种情况下,当其他属性,不缩放正在变化
为了在特定的缩放情况下禁用datachchange,我只是将它分配给其他情况。
我使用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);
我不喜欢这些答案。$watch的第一个参数是要监视的内容,它接受属性名作为字符串或返回值的函数。只需使用函数&返回要监视的值。这里我使用lodash JS库来$watch一个基于真实对象的新对象,但是去掉了属性:
$scope.$watch(function() {
return _.omit($scope.config, 'scale');
}, function(oldVal, newVal) {
console.log(oldVal, newVal);
});
不带Lodash [blacklist properties]:
$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进行比较之前剥离不需要的属性。
据我所知没有,但是一个简单的检查就可以做到:
$scope.$watch('config', function(newValue, oldValue){
if (newValue.scale == oldValue.scale) {
// ignore this
return;
}
// continue...
}, true);
更好的解决方案可能是这个函数;
$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/
这个可以比以前更好;
代码: // 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);
源代码:http://jsfiddle.net/tursoft/5rLfr/2/
- 如何重写下面的函数,使其不会't用于循环
- 如何删除除冒号、数字和'上午'或者'下午'
- 如何“;过滤器”;或者以其他方式重构该数据
- 重写CSS:使用jquery显示none属性
- 哪个布尔运算更快<或者<=
- 重写需要javascript中带有import关键字的语法
- 模态提示-如何重写此代码
- 在编译阶段后创建新的DOM树,或者继续使用原始修改的DOM
- 或者在表单上选择默认选项文本(选择1)
- 如何重写一个方法,并且仍然能够在重写的方法中使用基方法
- 重写不带defineProperty的对象getter
- 如何重写Javascript If语句以选择Classes而不是ID's的HTML格式
- 将其中一个异步方法重写为使用promise的方法
- 使用jquery重写html数字
- 如何用javascript重写html文档
- 在类外重写Javascript方法,使用默认行为
- 试图修改此javascript代码以减小弹出窗口的大小,或者在用户单击框外时关闭
- Javascript:重写函数's原型——糟糕的做法
- JQuery是否有一个“;移动“;作用或者有没有一种更紧凑的方法来做到这一点
- AngularJS忽略被监视对象中的键,或者重写$watch监听器