2017-07-18 95 views
0

我设法创建了一个小例子,它可以直接使用并可以重现问题。它是一个滤波器,可以消除一个数组随机2元素:

<!DOCTYPE html> 
<html ng-app='myApp'> 
    <head> 
    <meta charset="utf-8" /> 
    <script src="https://code.angularjs.org/1.6.5/angular.js"></script> 
    <script> 
    angular.module('myApp', []) 
    .filter('random', function() { 
     return function(input) { 

      var a = Math.floor(Math.random()*input.length); 
      var b = Math.floor(Math.random()*input.length); 
      return input.filter(function(element, i){ 
       if (i !== a && i !== b){ 
        return element; 
       } 
      }); 
     }; 
    }) 
    .controller('Controlleur', function($scope) { 
     $scope.contacts = [ 
      {"name": "donatello", "tel": 12456}, 
      {"name": "michaelangelo", "tel": 12456}, 
      {"name": "leonardo", "tel": 12456}, 
      {"name": "raphael", "tel": 12456}, 
      {"name": "robert", "tel": 12456}, 
     ] 
    }); 
    </script> 
</head> 
<body ng-controller="Controlleur"> 
    <ul> 
     <li ng-repeat="contact in contacts|random track by contact.name "> 
      <strong>{{contact.name}}</strong>: {{contact.tel}} 
     </li> 
    </ul> 
</body> 
</html> 

复制/粘贴,在一个文件中,加载在浏览器中的文件,并打开控制台。如果按F5键的时候了几个号码,你会看到的筛选器的工作,但你会随机得到:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [[{"msg":"fn: regularInterceptedExpression","newVal":21,"oldVal":18},{"msg":"fn: regularInterceptedExpression","newVal":"raphael"},{"msg":"fn: regularInterceptedExpression","newVal":"12456"},{"msg":"fn: regularInterceptedExpression","newVal":"robert"},{"msg":"fn: regularInterceptedExpression","newVal":"12456"}], 
... 

的问题是,它通常意味着$消化的连续触发次数太多。但是,我不会在任何地方明确更新范围。我只是在一个过滤器中创建一个新的数组,具有如此明显的副作用。

+0

您正在遍历联系人并同时对其进行筛选。这意味着你正在改变你正在迭代的数组。如果角度循环通过这个数组,并且它正在变化,那么也许你遇到了麻烦。我不会在这个地方使用过滤器。 –

+0

我不更改数组。 array.filter()生成一个新的数组。第一个没有修改。 –

回答

2

由于您每次摘要都返回数组中的随机项,因此范围永远不会稳定(每次都是相同的数组),并且一直在进行搜索以寻找它来稳定,然后它达到极限并中止。

一个修复将是使用$filter()在控制器传递新过滤阵列之前随机化一次查看和视图

.controller('Controlleur', function($scope, $filter) { 
    $scope.contacts = [ 
     {"name": "donatello", "tel": 12456}, 
     {"name": "michaelangelo", "tel": 12456}, 
     {"name": "leonardo", "tel": 12456}, 
     {"name": "raphael", "tel": 12456}, 
     {"name": "robert", "tel": 12456}, 
    ]; 

    $scope.randomContacts = $filter('random')($scope.contacts); 

}); 

视图中取出的随机过滤器:

<li ng-repeat="contact in randomContacts track by contact.name "> 
    <strong>{{contact.name}}</strong>: {{contact.tel}} 
</li> 

DEMO

+0

哦,所以角度预防性地运行$消化几次,即使范围内没有任何变化? –

+0

是的...在摘要循环中最少2次以肮脏检查整个范围。因此,视图逻辑中生成的任何随机事件都会导致问题 – charlietfl

0

I实际上找到了比@ charlietfl更好的解决方案(对于我的用例):将过滤器级别的随机结果缓存在关闭中,并在摘要期间返回该结果而不是随机结果。当我需要一个新的随机值时,我可以在这个时间间隔内高速缓存,而我在$ interval中完成了这个任意值。

我让他的“接受答案”的旗帜,因为他解释了为什么,而不仅仅是如何。

相关问题