2015-02-10 22 views
1

我是AngularJS的新手,我想了解更多关于ng-repeat的可能性。我已经编写了一些代码来尝试和学习更多,但是我遇到了一些我不明白的问题。在函数中使用ng-repeat中的数据

下面是代码:

的HTML:

<ul class="list-unstyled"> 
    <li ng-repeat="worker in workers"> 
     <section class="well col-md-6 col-md-offset-3"> 
      <h1 class="h3 col-md-6 text-right" style="margin-top: 0"><a>{{worker.worker_name}} {{ getTipCount(worker.id) }}</a></h1> 
     </section> 
    </li> 
</ul> 

在我的控制器:

$scope.getTipCount = (workerId) -> 
     WorkerTips = $resource("/workers/#{workerId}", { workerId: "@id", format: 'json' }) 
     json = WorkerTips .get ((res) -> 
     $scope.workertipscount = res.worker.tips.lengh 
    ) 

在JSON每个工人对象有尖端阵列和我是什么试图做的是得到每个工作者有多少技巧。为此,我需要通过ng-repeat从工作人员那里获得id,然后将其传递给一个函数,然后从JSON中获取提示数并将其显示在页面上。

然而,当我尝试这样做,它看起来像的页面进入一个无限循环,我得到以下错误:

Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

所以我猜我的方法来拉动信息从一个元素一个ng-repeat,然后将它发送到一个也发送到ng-repeats视图的函数是不正确的?如果是这样的AngularJS的正确方法是什么?

+0

这是一个错误或错误的代码? - 'res.worker.tips.lengh' – haxtbh 2015-02-10 13:41:28

+0

为什么不先计算每个工作人员的负载控制器的提示,然后做一些像getWorkersTip(id)'而不是每一次点击发送请求? – dcodesmith 2015-02-10 13:44:08

回答

5

的问题是,你调用一个函数,这将导致对$scope绑定值,这反过来将再次执行功能......等等等等的修改...

你应该更改代码这一点点:

{{ getTipCount(worker.id) }} 

为了这样的事情:

{{ workertipscount }} 

而且,这似乎是你在这里设置一个全局变量:

$scope.workertipscount = res.worker.tips.lengh 

相反,你可以直接设置该到工人对象本身:

<!-- Send in the entire worker object --> 
ng-click="getTipCount(worker)" 

//Now you can set properties directly on 
// the worker 
$scope.getTipCount = (worker) -> 
     WorkerTips = $resource("/workers/#{worker.id}", 
      { workerId: "@id", format: 'json' }) 

     json = WorkerTips.get ((res) -> 
     worker.tipCount = res.worker.tips.length; 
    ) 

<!-- And then just bind to that property --> 
{{ worker.tipCount }} 

这仅仅是一个建议,和一个你肯定不会纷纷效仿,但我发现,这种方法使生活变得更容易。

更新:

根据您在下面的评论,我建议干脆预先计算这个信息时,收集负载。我假设你是从一个AJAX调用加载集工,所以你可能有这样的事情:

someMethodToGetWorkers() 
    .then(function(workers){ 
    $scope.workers = workers; 
    }) 
    .then(function(){ 
    angular.forEach($scope.workers, function(worker){ 
     //Make call to populate worker tips 
    }); 
    }); 

这将熄灭的填充每个工人的技巧,如果你将它们保存到工人对象本身,那么你可以直接绑定到你的ng-repeat,正如我上面提到的。

作为一个注意事项,让这么多次回到服务器是非常不利的,特别是如果你有一个大集合,因为浏览器在同一个域的6个并发请求的上限。

您可能会考虑对您的API进行重新加工,该API会首先返回工作人员列表,以便简单地继续并包含数据以计算其提示数。

说明:

Angular uses dirty checking。这意味着它会将旧值与新值进行比较,以确定是否应采取行动。它通过一个$digest循环完成此操作。

$digest循环将旋转$scope中的每个值,并将其与基于创建的$watchers的旧值进行比较。任何时候您使用{{ }}语法创建一个观察器。

Angular持续执行此循环,直到没有检测到更改。

在函数表达式的情况下,角没有办法知道是否值不执行功能改变......在这种情况下它会导致一个肮脏的状态。因此,这个过程是无限重复的,直到10次迭代的失败保护和角度呕吐。

通常最好避免使用函数表达式,如{{ foo() }},因为它们将在$digest的每个循环中执行。

+3

杜,你快! – Manube 2015-02-10 13:44:28

+0

谢谢@Josh这真的是很好的信息。一件事是,我在代码中的ng-click只是作为一个测试,是否有可能在不使用ng-click的情况下进行描述? – 2015-02-12 10:33:33

+0

正如我需要在每次重复迭代时从Worker中拉出id并将其传递给函数,但是如果我不应该在ng中重复调用函数,那么在Angular中执行此操作的最佳方法是什么? – 2015-02-12 12:02:27

相关问题