在函数中使用来自 ng-repeat 的数据
Using data from an ng-repeat in a function
我是 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>
在我的控制器中:
$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 的正确方法是什么?
问题是您正在调用一个函数,这将导致修改 $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 首先 returns 工人列表,以便简单地继续并包括他们的小费计数数据。
解释:
Angular uses dirty checking。这意味着它将旧值与新值进行比较,以确定是否应采取行动。它通过 $digest
循环实现此目的。
$digest
循环遍历 $scope
中的每个值,并根据已创建的 $watchers
将其与旧值进行比较。任何时候你使用 {{ }}
语法你都在创建一个观察者。
Angular 一直执行这个循环,直到没有检测到变化。
在函数表达式的情况下,Angular在不执行函数的情况下无法知道值是否已更改...在这种情况下会导致处于肮脏状态。因此,该过程无限重复,直到 10 次迭代的故障保护启动并且 Angular 呕吐。
一般来说,最好避免像 {{ foo() }}
这样的函数表达式,因为它们会在 $digest
.
的每个循环中执行
我是 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>
在我的控制器中:
$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 的正确方法是什么?
问题是您正在调用一个函数,这将导致修改 $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 首先 returns 工人列表,以便简单地继续并包括他们的小费计数数据。
解释:
Angular uses dirty checking。这意味着它将旧值与新值进行比较,以确定是否应采取行动。它通过 $digest
循环实现此目的。
$digest
循环遍历 $scope
中的每个值,并根据已创建的 $watchers
将其与旧值进行比较。任何时候你使用 {{ }}
语法你都在创建一个观察者。
Angular 一直执行这个循环,直到没有检测到变化。
在函数表达式的情况下,Angular在不执行函数的情况下无法知道值是否已更改...在这种情况下会导致处于肮脏状态。因此,该过程无限重复,直到 10 次迭代的故障保护启动并且 Angular 呕吐。
一般来说,最好避免像 {{ foo() }}
这样的函数表达式,因为它们会在 $digest
.