【问题标题】:unexpected behavior of ng-repeatng-repeat 的意外行为
【发布时间】:2015-03-27 15:13:16
【问题描述】:

我有一个带有 ng-repeat 的 Angular(1.2.1) 应用程序,如下所示:

<div ng-repeat="item in list | filter:filterList | orderBy:orderList" my-dir>

filterList 看起来像这样:

$scope.filterList = function(x){
     if (Service.active()){ //tells me whether I need to filter by this field at all
         if (x.field != Service.field()) {
             console.log('FALSE:' + x.id) 
             return false;
         }
     }
      else {...}
    //other clauses like above 
     return true;
} 

orderList 看起来像:

$scope.orderList = function(x){
     return (x.value);
}

我看到的意外行为是,当 Service.foo() 和/或 Service.field( ) 发生变化时,我希望列表的内容会发生变化。确实如此 - 与新值匹配的项目出现在我的列表顶部,按value 排序,正如预期的那样。但是,以前在列表中但应该被删除的项目仍然保留在列表中,按照相同、正确的value-sorted 顺序,在应该在列表中的项目下方.

澄清:如果Service.field() == 'a' 并且列表包含对象:

field = 'a' value='3'
field = 'a' value='2'
field = 'a' value='1'

然后'Service.field()' 更改为'b',我希望看到

field = 'b' value='3'
field = 'b' value='2'
field = 'b' value='1'
//nothing else 

但我看到的是:

field = 'b' value='3'
field = 'b' value='2'
field = 'b' value='1'
field = 'a' value='3'
field = 'a' value='2'
field = 'a' value='1'

假设这是服务更改未应用于范围的问题 - 但 a) 我已确保更新范围; b) 如果是这样,列表将是:

field = 'a' value='3'
field = 'b' value='3'
field = 'a' value='2'
field = 'b' value='2'
field = 'a' value='1'
field = 'b' value='1'

因为orderList 只看字段,只看值。

究竟是什么导致了这种情况?

更新:我忘了提到过滤器函数中的 console.log() 语句确实打印了我不希望出现在列表中的项目 - 所以过滤器函数正在返回false,但项目不会被删除。

更新 #2:哇。因此,我突然想到,过滤器函数中可能会抛出和吞噬异常并导致此行为。所以,我在它的最上面扔了一个i = 3/0,果然,控制台没有抛出异常。我现在正在调查。但是得到这个:bug 已修复! 带有过滤器功能的重复,现在显然已损坏,按预期工作。我怀疑这是关于我的问题的有力线索,但我还没有弄清楚线索指向什么。

【问题讨论】:

  • 2 else for 相同 if?是错字吗?
  • 确实如此,@Brian - 感谢您指出这一点
  • Service.field() 改变时,你确定Service.foo() 返回相同的值吗?
  • @zsong:是的,我是。请参阅更新以获取说明。

标签: javascript angularjs


【解决方案1】:

ng-repeatlist绑定数据,列表对象不变,所以不会调用过滤函数。

您应该从其他地方更新您的列表数据,因此,请反复检查和更新列表数据,例如:

var checkList = function() {
  $scope.list.forEach(function(data) {
    if (Service.foo()) {data.isShow = true;} // set a mark to display or not
  });
}
$timeout(checkList, 5000); // check every 5 seconds.

然后在您的 ng-repeat 中,使用该标记来确定是否显示。

<div ng-repeat="item in list | filter: {isShow: true} | orderBy:orderList" my-dir>

【讨论】:

  • 这是不真实的。过滤器函数在我期望的时候被调用,正如打印语句所确认的那样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-24
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多