Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/414.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在错误的时间调用筛选集合上的Angular watch侦听器_Javascript_Angularjs - Fatal编程技术网

Javascript 在错误的时间调用筛选集合上的Angular watch侦听器

Javascript 在错误的时间调用筛选集合上的Angular watch侦听器,javascript,angularjs,Javascript,Angularjs,我有一个有趣的问题,就是使用AngularJS查看对过滤集合的更改 我的范围中有一个项目集合,该集合使用其属性之一进行过滤,并使用ng repeat进行呈现: <input ng-model="searchName" placeholder="search"/> <ul> <li ng-repeat="i in (filteredItems = (items | filter:searchName))">

我有一个有趣的问题,就是使用AngularJS查看对过滤集合的更改

我的范围中有一个项目集合,该集合使用其属性之一进行过滤,并使用
ng repeat
进行呈现:

    <input ng-model="searchName" placeholder="search"/>
    <ul>
        <li ng-repeat="i in (filteredItems = (items | filter:searchName))">
            {{i.name}}
        </li>
    </ul>
我在控制器中为
filteredItems
注册了一个侦听器:

$scope.$watch('filteredItems', function(newItems, oldItems) {
    $scope.filteredItemsLen = newItems.length;
}, true);
但是,在对
filteredItems
进行更改时,并不总是调用此侦听器。在下面的小提琴中,请尝试以下方法:

  • 将“aa”放入过滤器输入:显示的列表得到更新, 未调用侦听器,因此显示的长度错误
  • 将“aaa”放入过滤器输入:显示的列表得到更新, 调用listener两次(首先使用上一个筛选器中的数据,然后使用当前数据),显示的长度是正确的
  • 这是小提琴。请查看控制台日志以查看侦听器何时实际被调用

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

    关于AngularJS有什么我不明白的吗?有什么想法吗?

    我不太清楚它为什么这么做,但它似乎在推迟它的消化周期。除非你想去调试angular来找出原因,否则我建议两种选择

    在大多数情况下,当您不想更改作用域本身的某些内容时,会使用手动监视(即监视更改并调用另一个函数,而不是修改作用域)。您想要实现的目标与计算可观测的概念密切相关,但同时,您只从另一个对象返回属性,而不进行转换

    直接使用属性

    在模板中,您可以直接使用
    filteredItems.length
    。因为它是一个数字,所以即使底层数组发生变化,angular也会在摘要周期中实现稳定性

    <p>filtered items length: {{filteredItems.length}}</p>
    

    编辑:这是第二个选项的错误

    我认为这是JSFIDLE使用的Angular 1.1.1中的错误。如果您更新到1.1.5,它将如您所期望的那样工作,$watch将在每次筛选匹配数更改时运行-


    是的,它适用于1.1.5,谢谢。事实上,angular的所有早期版本都有这个问题,例如stable 1.0.7。返回length属性只是为了简化我的情况。我想要实现的是基于可见项的某些属性计算一些值。您提出的第二个选项(计算属性)实际上比我的观察者更好。
    <p>filtered items length: {{filteredItems.length}}</p>
    
    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>