NG-repeat中复制项目时的奇怪行为Angular 1.3

时间:2015-07-01 11:44:32

标签: angularjs

我在Angular 1.3中出现了一个非常奇怪的行为:

当我改变

时会发生这种情况
 {{item}}

进入:

 {{::item}}

并单击“复制”按钮;它假设要做的是复制给定索引处的项目并将其放在源项目下面。它的作用是复制列表中的最后一项,并将其添加到列表的底部!

HTML:

<div ng-app="myApp">
    <div ng-controller="MyCtrl">
        <ul>
           <li ng-repeat="item in items track by $index">{{::item}}</li>
        </ul>
        <input ng-model="newItem" type="text"></input>
        <button ng-click="add(newItem)">Add</button>
        <button ng-click="copy(newItem)">Copy</button>
    </div>
</div>

JavaScript:

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

app.controller('MyCtrl', function($scope) {
    $scope.items = ["A", "B", "C", "D"];
    $scope.add = function(item) {
       $scope.items.push(item);
    };
    $scope.copy = function(item) {
       var newItem = angular.copy($scope.items[parseInt(item)]);
       $scope.items.splice(parseInt(item) + 1, 0, newItem);
    };    
});

有人知道引擎盖下发生了什么事吗?

这是一个小提琴:http://jsfiddle.net/v87kgwud/14/

2 个答案:

答案 0 :(得分:0)

我认为Sidharth Panwar的回答大部分是正确的,除了一个。

<强>说明: 列表的初始状态为['A', 'B', 'C', 'D'],前4个元素一次有界(即其值的变化不会反映在UI上),但无论如何,如果输入在0-3范围内,一个新元素被添加到列表中,列表中的最后一个字符'D'被推到第五位。由于列表中第5位的项目不是一次限制,因此在列表中呈现新的D.

<强>微量

  1. 初始状态: ['A', 'B', 'C', 'D']
  2. 通过将0作为文本框的输入来复制“A”
  3. 新州: ['A','A','B', 'C' ,'D']
  4. 由于前4个元素是一次有界,因此列表不会更改第一个摘要周期中绑定的值,但是由于在第五个位置找到了一个新元素,因此必须对该新元素执行一次绑定。元件。

    在列表中的D之前或之处添加任何元素会将最后一个元素移动一个位置,因为这个新元素没有绑定,所以创建了一次绑定。但在这种情况下,似乎新元素将始终为'D',因为它位于列表的尾部。

    希望这有帮助!

答案 1 :(得分:-1)

这是我在角度documentation中找到的内容:
以::开头的表达式被视为一次性表达式。一次性表达式将在稳定后停止重新计算。

这实际上意味着当正在呈现页面并且ng-repeat运行时,迭代正确发生并且值以正确的顺序打印。 ng-repeat结束后,分配给{{:: item}}的值为&#39; D&#39;。如果收集长度发生变化,ng-repeat将添加一个新项目,但该项目每次都是D,因为{{:: item}}解析为D.无论复制功能是否正常工作并添加正确的内容,都会发生这种情况。元素集合。所以,你的收藏不再是事实的来源。这就是一次性绑定意味着 - 您不再连接到源。这里是完整的逐字: 为什么这个功能 一次性绑定表达式的主要目的是提供一种创建绑定的方法,该绑定在绑定稳定后取消注册并释放资源。减少被监视的表达式数量可以使摘要循环更快,并允许同时显示更多信息。

  

为何选择此功能

     

一次性绑定表达的主要目的是提供一种方法   创建一个取消注册的绑定并释放一次资源   绑定是稳定的。减少表达式的数量   观察使得摘要循环更快并允许更多信息   同时显示。

     

价值稳定算法

     

一次性绑定表达式将保留表达式的值   在摘要周期结束时,只要该值未定义。   如果表达式的值是在摘要循环中设置的   之后,在同一个摘要循环中,它被设置为undefined,然后是   表达未得到满足,并将继续受到关注。

     
      
  1. 给定一个以::开头的表达式,当输入摘要循环并对表达式进行脏检查时,将值存储为V
  2.   
  3. 如果未定义V,请将表达式的结果标记为“稳定”并安排任务以在此表达式中取消注册该表达式   我们退出摘要循环
  4.   
  5. 正常处理摘要循环
  6.   
  7. 当完成摘要循环并且所有值都已结算时,处理监视撤销注册任务的队列。对于每个手表   取消注册,检查它是否仍然评估为不是的值   未定义。如果是这种情况,请取消注册手表。否则,保持   在以后的消化循环中检查手表,方法是按照   从步骤1开始的相同算法
  8.