在ng-repeat上填充新数组

时间:2015-11-18 12:54:45

标签: javascript arrays angularjs

$scope一个数组,包含控制器上的Code和Amount。在计算函数的摘要时,浏览器会收到由无限循环引起的未捕获Error: 10 $digest() iterations reached. Aborting!错误(奇怪但它正在工作)。

有没有正确的方法在ng-repeat期间组合新数组而不会出现无限循环错误?

任何帮助将不胜感激

jsFiddle Link

更新:行变量不是静态的,可以添加,修改或删除。 jsFiddle Line for Update

var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
    $scope.Lines = [ {Code:'X', Amount:'10'},
                       {Code:'Y', Amount:'10'}, 
                       {Code:'Z', Amount:'20'},
                       {Code:'Y', Amount:'1'}];

    $scope.Sums =  function(){
        var sums = new Array();
        for (var i = 0; i < $scope.Lines.length; i++) {
            var added = false;
            for (var j = 0; j < sums.length; j++) {
                if (sums[j].Code == $scope.Lines[i].Code) {
                    sums[j].Amount = parseFloat( sums[j].Amount) + parseFloat($scope.Lines[i].Amount);
                    added = true;
                    break;
                }
            }
            if (!added) {
                sums.push( { Code:$scope.Lines[i].Code,  Amount: $scope.Lines[i].Amount  } );
            }
        }
        return sums;
    }
}

HTML:

<div ng-controller="MyCtrl">
   <table style="border:  1px solid black;">
      <tr ng-repeat="line in Lines">
         <td>{{ line.Code }}</td>
         <td>{{ line.Amount }}</td>
      </tr>
   </table>
   Summary 
   <table style="border:  1px solid black;">
      <tr ng-repeat="sum in Sums()">
         <td>{{ sum.Code }}</td>
         <td>{{ sum.Amount }}</td>
      </tr>
   </table>
</div>

4 个答案:

答案 0 :(得分:2)

如果你这样做,这仍然会发生:

public static class Process1 implements CSProcess {

    private ChannelOutputInt output;

    public Process1(ChannelOutputInt out) {
        output = out;
    }

    @Override
    public void run() {
        for (int i = 0; i < 1; i++) {
            System.out.println("Written...");
            output.write(5);
        }
        output.write(-1);
    }

}

public static class Process2 implements CSProcess {

    private ChannelInputInt input;

    public Process2(ChannelInputInt in) {
        input = in;
    }

    @Override
    public void run() {
        int x = 0;
        while ((x = input.read()) > 0) {
            System.out.println(x);
        }
    }

}

public static void main(String[] args) {

    One2OneChannelInt chan = Channel.one2oneInt();

    Process1 process1 = new Process1(chan.out());
    Process2 process2 = new Process2(chan.in());

    Parallel parallel = new Parallel();

    parallel.addProcess(process1);
    parallel.addProcess(process2);
    parallel.run();
}

请注意,一旦通过angular观察Sums,就永远不要创建新数组。如果您需要清空它,请使用var myApp = angular.module('myApp',[]); function MyCtrl($scope) { $scope.Lines = [ {Code:'X', Amount:'10'},{Code:'Y', Amount:'10'}, {Code:'Z', Amount:'20'},{Code:'Y', Amount:'1'}]; $scope.Sums = []; calculate(); var calculate = function(){ $scope.Sums.length = 0; for (var i = 0; i < $scope.Lines.length; i++) { var added = false; for (var j = 0; j < $scope.Sums.length; j++) { if ($scope.Sums[j].Code == $scope.Lines[i].Code) { $scope.Sums[j].Amount = parseFloat( $scope.Sums[j].Amount) + parseFloat($scope.Lines[i].Amount); added = true; break; } } if (!added) { $scope.Sums.push( { Code:$scope.Lines[i].Code, Amount: $scope.Lines[i].Amount } ); } } } }

在您的观点中:$scope.Sums.length = 0

答案 1 :(得分:1)

我宁愿在$watch上添加一个$scope.Lines来创建一个数组并将其填充为$scope.sums,这样ng-repeat就不必一次又一次地调用该方法。见Fiddle

编辑(为深度观看添加缺少的参数):

Fiddle

答案 2 :(得分:1)

由于Andre Kreienbring指出问题是因为您的sum()正在返回一个对象。

我建议使用过滤器来完成你需要的东西,就像这样

<强> HTML

<div ng-controller="MyCtrl">
    <table style="border:  1px solid black;">
      <tr ng-repeat="line in Lines">
           <td>{{ line.Code }}</td>
           <td>{{ line.Amount }}</td>
      </tr>
     </table>
    Summary 
      <table style="border:  1px solid black;">
      <tr ng-repeat="sum in Lines | unique : 'Code'">
           <td>{{ sum.Code }}</td>
           <td>{{ Lines | filter: { Code: sum.Code } : true | sum: 'Amount' }}</td>
      </tr>
     </table>
</div>

<强>脚本

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.Lines = [ {Code:'X', Amount:'10'},{Code:'Y', Amount:'10'}, 
                    {Code:'Z', Amount:'20'},{Code:'Y', Amount:'1'}];
}


myApp.filter('unique', function() {
    return function(input, key) {
        var unique = {};
        var uniqueList = [];
        for(var i = 0; i < input.length; i++){
            if(typeof unique[input[i][key]] == "undefined"){
                unique[input[i][key]] = "";
                uniqueList.push(input[i]);
            }
        }
        return uniqueList;
    };
});

myApp.filter('sum', function() {
    return function(input, key) {
        var sum = 0;
        for(var i = 0; i < input.length; i++){
            sum += Number(input[i][key]);
        }
        return sum;
    };
});

唯一过滤器来自https://stackoverflow.com/a/18382680/360067

小提琴 - http://jsfiddle.net/34od99sz/

答案 3 :(得分:0)

如果我没有弄错线

for (var j = 0; j < sums.length; j++) 

你试图获取总和的长度,这是一个新的数组。它没有长度。另外你为什么要用

 var sums = new Array();

初始化数组而不是

var sums = [];