我有一个表,用户可以根据这些列的某些列和某些值来选择过滤表中的行。跟踪此过滤器的对象结构如下所示:
$scope.activeFilterAttributes = [
{
"columnName": "city",
"values": ["LA", "OT", "NY"]
},
{
"columnName": "weather",
"values": ["humid", "sunny"]
}
];
因此,数组中的对象包含“columnName”和“values”键。 “columnName”表示要为过滤器考虑的列,而“values”包含过滤器值。基本上,上面的数组将导致表中的行,其中city列包含“LA”,“OT”或“NY”作为值,而weather列包含“湿”或“晴天”作为值。不显示不包含这些值的其他行。
为了更好地理解这个对象,如果用户只希望在“city”列中看到那些“LA”或“NY”的行,则结果数组将如下所示:
$scope.activeFilterAttributes = [
{
"columnName": "city",
"values": ["LA", "NY"]
},
{
"columnName": "weather",
"values": []
}
];
用户设置或删除这些过滤器。只要发生这种情况,就会更新上面的数组。 此更新正确发生,我已经验证了 - 这里没问题。
问题出在$ watch()上。我有以下代码:
$scope.$watch('activeFilterAttributes', function() {
//Code that should update the rows displayed in the table based on the filter
}}
当用户在UI中更新过滤器时,$scope.activeFilterAttributes
已正确更新,但更新时不会触发$ watch。它是在应用程序加载时第一次触发,但未来的更新对此没有影响。
我创造了一个小提琴来证明这一点:http://jsfiddle.net/nCHQV/
在小提琴中,$scope.info
表示表格的行,可以这么说;
$scope.data
代表过滤器
单击该按钮相当于更新过滤器(在小提琴的情况下 - 数据),从而更新表中显示的行(在小提琴的情况下 - 信息)。但是可以看出,单击按钮时信息不会更新。
当对象数组发生变化时,不应该触发$scope.$watch
吗?
答案 0 :(得分:66)
$watch
方法使用一个名为objectEquality
的可选第三个参数来检查两个对象是否相等,而不是仅共享相同的引用。这不是默认行为,因为它比参考检查更昂贵。您的手表未被触发,因为它仍然指向同一个物体。
有关详细信息,请参阅docs。
$scope.$watch('activeFilterAttributes', function() {
// ...
}, true); // <-- objectEquality
添加该参数,一切顺利。
答案 1 :(得分:5)
现在接受的答案有点过时了,与AngularJS 1.1.4一样,$WatchCollection
函数被添加用于数组和其他集合,这比带有深度的$Watch
要便宜得多-equality标志设置为true。
所以这个新功能现在在大多数情况下都是可取的。
有关$watch
函数