Angularjs 为什么ng单击复选框会在调用函数后更新数组的值?

Angularjs 为什么ng单击复选框会在调用函数后更新数组的值?,angularjs,checkbox,Angularjs,Checkbox,我有一组有分数的人。我将显示人员列表及其分数和复选框。当用户选中该复选框时,我会合计所有选中的分数: 但是,由于Angular在执行ng click中包含的功能时,似乎没有更新ng model的值,因此总计落后了一次检查 如何让Angular先更新值,然后执行函数? <div ng-controller="MyCtrl"> <ul> <li ng-repeat="person in persons | orderBy:'score'">

我有一组有分数的人。我将显示人员列表及其分数和复选框。当用户选中该复选框时,我会合计所有选中的分数:

但是,由于Angular在执行
ng click
中包含的功能时,似乎没有更新
ng model
的值,因此总计落后了一次检查

如何让Angular先更新值,然后执行函数?

<div ng-controller="MyCtrl">
    <ul>
        <li ng-repeat="person in persons | orderBy:'score'"><input type="checkbox" ng-model="person.isChecked" ng-click="updateTotals()"/> {{person.name}} = {{person.score}} ({{person.isChecked}}) 

        </li>
    </ul>
    <div>{{message}}</div>
    <div>total score of checked persons: {{total}}</div>
</div> 

{{message}} 被检查人的总分:{{total}

var myApp=angular.module('myApp',[]);
函数MyCtrl($scope$window){
$scope.debug='';
$scope.total=0;
$scope.persons=[
{分数:1,名字:'Jim',被检查为:true},
{分数:2,名字:'Joe',被选中:false},
{分数:3,名字:'Angie',被检查为:true}
];
$scope.updateTotals=函数(){
$scope.total=0;
对于(变量x=0;x<$scope.persons.length;x++){
var person=$scope.persons[x];
如果(人员['isChecked']){
$scope.total+=人['score'];
}
}
}
$scope.updateTotals()
}

不要自己更新视图数据,请使用数据绑定。只需将您的
updateTotals
-函数重命名为
getTotal
,并使其返回计算的总数:

$scope.getTotal = function() {
    var total = 0;

    for(var x=0; x < $scope.persons.length; x++) {
        var person = $scope.persons[x];
        if(person['isChecked']) {
            total += person['score'];   
        }
    }

    return total;
}
现在,您可以删除复选框上的
ng单击
,让angular为您完成工作


另一方面,我建议您研究并开始使用它。

这是因为
ng click
是在
ng model
更改之前触发的,因此您需要使用
ng change
而不是
ng click

<li ng-repeat="person in persons | orderBy:'score'">
    <input type="checkbox" ng-model="person.isChecked" ng-change="updateTotals(person)"/>
    .....
</li>
在html中

<ul>
    <li ng-repeat="person in persons | orderBy:'score'" ng-init="person.isChecked ? (all.total = all.total+person.score) : return">
        <input type="checkbox" ng-model="person.isChecked" ng-change="person.isChecked ? (all.total = all.total+person.score) : (all.total = all.total-person.score)"/>
        {{person.name}} = {{person.score}} ({{person.isChecked}})
    </li>
</ul>
更改复选框值时添加或扣除分数

<input type="checkbox" ng-model="person.isChecked" ng-change="person.isChecked ? (all.total = all.total+person.score) : (all.total = all.total-person.score)"/>
内部控制器

// using a object because we need this inside `ng-repeat` which create a child scope, otherview we need to call it as $parent.total in the view.
$scope.all = {
    total: 0
};
$scope.updateTotal = function(person, isInitPhase) {
    if (isInitPhase) {
        if (person.isChecked) {
            $scope.total += person.score;
        }
    } else {
        if (person.isChecked) {
          $scope.total += person.score;
        } else {
            $scope.total -= person.score;
        }
    }
}
这是你的电话号码


我选择最后一个,因为我觉得它干净多了。

我认为您可以使用ng change而不是ng-click。虽然这样做有效,但它仍然是一种反模式
...ng-init="person.isChecked ? (all.total = all.total+person.score) : return"...
<input type="checkbox" ng-model="person.isChecked" ng-change="person.isChecked ? (all.total = all.total+person.score) : (all.total = all.total-person.score)"/>
<li ng-repeat="person in persons | orderBy:'score'" ng-init="updateTotal(person, true)">
    <input type="checkbox" ng-model="person.isChecked" ng-change="updateTotal(person, false)"/>
    {{person.name}} = {{person.score}} ({{person.isChecked}})
</li> 
$scope.updateTotal = function(person, isInitPhase) {
    if (isInitPhase) {
        if (person.isChecked) {
            $scope.total += person.score;
        }
    } else {
        if (person.isChecked) {
          $scope.total += person.score;
        } else {
            $scope.total -= person.score;
        }
    }
}