过滤集合上的Angular watch侦听器在错误的时间调用
Angular watch listener on filtered collection called at the wrong time
我有一个有趣的问题,那就是使用AngularJS监视对已过滤集合的更改。
我的作用域中有一组项目,这些项目使用其属性之一进行筛选,并使用ng-repeat
:进行渲染
<input ng-model="searchName" placeholder="search"/>
<ul>
<li ng-repeat="i in (filteredItems = (items | filter:searchName))">
{{i.name}}
</li>
</ul>
我想观察对filteredItems
的更改,以便更新依赖于当前可见项的范围变量。对于这个例子,假设我想更新一个保持当前filteredItems
长度的变量,并将其显示给用户:
<p>filtered items length: {{filteredItemsLen}}</p>
我在我的控制器中注册了filteredItems
的侦听器:
$scope.$watch('filteredItems', function(newItems, oldItems) {
$scope.filteredItemsLen = newItems.length;
}, true);
然而,在对filteredItems
进行更改时,并不总是调用此侦听器。在下面的小提琴里,请试试这个:
- 在过滤器输入中输入"aa":显示的列表得到更新,listener未调用,因此显示的长度错误
- 在过滤器输入中输入"aaa":显示的列表得到更新,listener被调用两次(首先使用来自上一个过滤器的数据,然后使用当前数据),显示的长度是正确的
这是小提琴。请查看控制台日志,了解实际调用侦听器的时间。
http://jsfiddle.net/7QJJK/8/
有趣的观察:如果我在页面上的某个地方使用{{filteredItems}}
,那么侦听器就会被正确调用。
AngularJS有什么我不理解的地方吗?有什么想法吗?
我不太确定为什么要这样做,但它似乎在推迟其消化周期。除非你想调试angular本身以找出原因,否则我建议两种选择。
在大多数情况下,当您不想更改作用域本身的内容时,会使用手动监视(即监视更改并调用另一个函数,而不是修改作用域)。你想要实现的是与计算可观测的概念密切相关的,但同时,你只从另一个对象返回一个属性,而不转换它
直接使用属性
在模板中,可以直接使用filteredItems.length
。因为它是一个数字,所以即使底层数组发生变化,angular也会在摘要周期中实现稳定。
<p>filtered items length: {{filteredItems.length}}</p>
在作用域上使用计算属性
由于filteredItems
会在某个时刻出现在作用域上,所以这太过分了(除非您计算长度并返回不同的内容)。在范围中,您可以定义一个返回值的函数,angular将很高兴地观察其摘要周期中的变化:
function SomeCtrl($scope) {
$scope.items = [{name: 'aa'}, {name: 'ab'}, {name: 'ac'}];
$scope.filteredItemsLen = function() {
return ($scope.filteredItems || []).length;
};
$scope.$watch('filteredItemsLen()', function(newValue, oldValue) {
console.log('Filtered length changed from ' +
oldValue + ' to ' + newValue);
});
}
<p>filtered items length: {{filteredItemsLen()}}</p>
编辑:这是第二个选项的更新小提琴
我认为这是jsfiddle使用的Angular 1.1.1中的一个错误。如果你更新到1.1.5,它会像你预期的那样工作,每次过滤匹配的数量改变时都会运行$watchhttp://jsfiddle.net/7QJJK/10/
- Jquery函数在错误的时间提交
- Javascript设置日期不起作用,显示错误的时间
- Jquery 日期时间选取器错误
- 时刻.js时区值返回错误的时间戳
- 高图表日期时间从错误的日期开始
- 完整的日历错误时间在点击事件谷歌日历
- 使用cordova的android设备上的时间错误,但浏览器中的时间正确
- 检查JavaScript中的日期时间是否相等时出现错误结果
- jQuery setTimeout ajax递归函数在即时消息程序中短时间后抛出错误
- UTC Woes,Flot X轴时间错误
- 谷歌分析/Mixpanel/等.确定时钟错误时的事件时间戳
- new Date返回NaN或从服务器日期()开始的错误时间
- 为什么我从时间戳中得到错误的日期
- 在带有时间戳的日期之间计算时出现 NaN JavaScript 错误
- Chrome 扩展程序弹出窗口关闭在错误的时间触发
- 通过Javascript错误将考试时间设置为30分钟
- jQuery localtime,收到不受支持的日期/时间字符串错误
- j查询返回错误时间的日期格式
- 显示错误时间的完整日历月视图
- 谷歌融合表查询错误-时间比较