gpt4 book ai didi

javascript - 过滤集合上的 Angular watch 监听器在错误的时间调用

转载 作者:行者123 更新时间:2023-11-30 12:58:32 27 4
gpt4 key购买 nike

我在使用 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>

我在我的 Controller 中为 filteredItems 注册了一个监听器:

$scope.$watch('filteredItems', function(newItems, oldItems) {
$scope.filteredItemsLen = newItems.length;
}, true);

然而,在对 filteredItems 进行更改时,并不总是调用此监听器。在下面的 fiddle 中,请试试这个:

  1. 将“aa”放入过滤器输入:显示的列表得到更新,监听器没有被调用所以显示的长度是错误的。
  2. 将“aaa”放入过滤器输入:显示的列表得到更新,监听器被调用两次(第一次使用前一个过滤器的数据,然后使用当前数据),显示的长度是正确的。

这是 fiddle 。请查看控制台日志以查看实际调用监听器的时间。

http://jsfiddle.net/7QJJK/8/

有趣的观察:如果我在页面的某处使用 {{filteredItems}},那么监听器会被正确调用。

AngularJS 有什么我不明白的地方吗?有什么想法吗?

最佳答案

我不太确定为什么它这样做,但看起来 angular 正在推迟它的摘要周期。除非您想调试 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>

编辑:这是updated fiddle对于第二个选项

关于javascript - 过滤集合上的 Angular watch 监听器在错误的时间调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18186824/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com