AngularJS ng-repeat一次绑定嵌套方法调用

时间:2015-06-12 16:36:38

标签: javascript angularjs

我正在尝试使用AngularJS 1.3(我刚刚从1.2迁移了我的应用)。我正在玩新的一次性绑定。我遇到过这种不起作用的情况,有人可以解释一下原因吗?我通过调用视图中的方法动态生成id字段。结果,一次性绑定似乎不起作用。见http://plnkr.co/edit/GyfKKb?p=preview

具体来说,我希望在将新元素添加到数组时,一次性不会重新呈现ng-repeat。但是将新元素推入数组(通过按钮单击)也会使新元素出现在ng-repeat的输出中。

的index.html

<body ng-controller="MainCtrl">
  <!-- TODO: I would expect addItemC() to do nothing with one time binding -->
  <button ng-click="addItemC()">add</button>

  <div ng-repeat="itemC in ::itemsC">

    <!-- dynamically generate id that is cause breakage -->
    {{::itemC.id() | limitTo:3}}

  </div>      
</div>

app.js

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {

  // generate random string id dynamically (code taken from stackoverlow answer)
  var itemObj = {
    id: function makeid() {
      var text = "";
      var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

      for( var i=0; i < 100; i++ )
          text += possible.charAt(Math.floor(Math.random() * possible.length));

      return text;
    }
  };

  // one time binding does not work
  $scope.itemsC = [
    angular.copy(itemObj),
    angular.copy(itemObj),
    angular.copy(itemObj)
  ];
  $scope.addItemC = function() {
    $scope.itemsC.push(angular.copy(itemObj));
  }
});

2 个答案:

答案 0 :(得分:2)

我认为这是因为ng-repeat angular内的$ digest循环次数超出抛出误差。主要是因为for循环运行每个项目100次迭代。

如果更改逻辑以在控制器内生成id,然后将项目赋予ng-repeat以进行渲染,那么它可以正常工作。看看我的plunkr

演示 http://plnkr.co/edit/4nFtOy1uGtDyUEWXCVbT?p=preview

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';

  // generate random string id dynamically (code taken from stackoverlow answer)
  function makeid() {
      var text = "";
      var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

      for( var i=0; i < 100; i++ )
          text += possible.charAt(Math.floor(Math.random() * possible.length));

      return text;
    }

  function getItem () {
    return {
      id: makeid()
    };
  }


  var itemObj = {
    id: makeid()
  };


  // one time binding does not work
  $scope.itemsC = [
    getItem(),
    getItem(),
    getItem(),
  ];
  $scope.addItemC = function() {
    $scope.itemsC.push(getItem());
  }

  $scope.removeItem = function(item) {
    var index = $scope.itemsC.indexOf(item);
    $scope.itemsC.splice(index, 1);
  }
});

标记内部将itemC.id()更改为itemC.id,因为ID现在属性。

答案 1 :(得分:2)

我认为因为你是一次性绑定函数并且每次调用函数。在双花括号内调用函数将给出函数返回的任何内容。通过保持返回随机字符串,函数保持不变。

因此,一次性绑定实际上可以通过保持调用相同的函数来实现。请注意,该功能不会更改。我添加了一个新属性,它不是对象的一个​​函数,以显示一次绑定实际工作。

<div style="font-weight:bold;">itemsC:</div>
<div ng-repeat="itemC in ::itemsC">
  <div ng-click="removeItem(itemC)">
    <!-- dynamically generate id -->
    {{::itemC.name | limitTo:3 }}
  </div>
</div>
<div style="margin-top:10px;">{{itemsC}}</div>

http://plnkr.co/edit/T8KRafey7VJFbcAs4NLZ?p=preview