使用函数中ng-repeat的数据

Don*_*rty 1 coffeescript angularjs angularjs-ng-repeat

我是AngularJS的新手,我正在尝试学习更多关于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>
Run Code Online (Sandbox Code Playgroud)

在我的控制器中:

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

在JSON中,每个工作者对象都有一系列提示,我想要做的是获得每个工作者有多少提示的计数.要做到这一点,我需要通过ng-repeat从worker获取id,然后将其传递给一个函数,然后从JSON中获取提示计数并将其显示在页面上.

但是,当我尝试这样做时,看起来页面进入无限循环,我得到以下错误:

错误:[$ rootScope:infdig] 10 $ digest()迭代达成.中止!

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

Jos*_*osh 5

问题是你正在调用一个函数,这将导致修改一个绑定值$scope,然后再次执行该函数......等等......

你应该改变这一点代码:

{{ getTipCount(worker.id) }}
Run Code Online (Sandbox Code Playgroud)

对于这样的事情:

{{ workertipscount }}
Run Code Online (Sandbox Code Playgroud)

此外,这似乎是您在此处设置的全局变量:

$scope.workertipscount = res.worker.tips.lengh
Run Code Online (Sandbox Code Playgroud)

相反,您可以将其直接设置到worker对象本身:

<!-- 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 }}
Run Code Online (Sandbox Code Playgroud)

这只是一个建议,你肯定不必遵循,但我发现这种方法使生活更容易.

更新:

根据您在下面的评论,我建议您在加载集合时预先计算此信息.我假设您正在从AJAX调用中加载一组worker,所以你可以这样:

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

这将填充每个工人提示填充,如果您将它们保存到工作对象本身,那么您可以在ng-repeat我上面提到的直接绑定它.

作为旁注,让这么多次返回服务器是非常有用的,特别是如果你有一个大的集合,因为浏览器会限制你同一个域的6个并发请求.

您可能会考虑重新处理返回工作人员列表的API,以便继续操作并包含其提示计数的数据.

说明:

Angular使用脏检查.这意味着它将旧值与新值进行比较,以确定是否应该执行操作.它通过$digest循环实现这一点.

$digest环在旋转中的每个值$scope,并将其与基于什么旧的价值$watchers已经建立.无论{{ }}何时使用语法,您都要创建一个观察者.

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

在函数表达式的情况下,Angular无法在不执行函数的情况下知道值是否已更改 ...在这种情况下,它会导致脏状态.因此,该过程无限重复,直到10次迭代的故障保护开始和Angular pukes.

一般来说,最好避免使用函数表达式,{{ foo() }}因为它们将在每个循环中执行$digest.

  • 呃,你快! (3认同)