2015-07-01 6 views
0

я придумал очень странное поведение в угловых 1.3:Weird поведения Угловой +1,3 при копировании элемент в NG-повторе

Это происходит, когда я меняю

{{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); 
    };  
}); 

Кто знает, что происходит под капотом?

Вот Fiddle: http://jsfiddle.net/v87kgwud/14/

+0

Как он узнает индекс? –

+0

Если вы откроете JSFiddle; как вы видите, элемент должен быть введен в текстовое поле. И.Е. когда вы наберете 0 и нажмите «Копировать», он должен скопировать «A» и поместить его под исходный элемент. –

+0

В принципе, я думаю, что AngularJS не вставляет новый элемент в DOM, он только толкает его в конце и обновляет соответствующие области. Но поскольку текстовое содержимое не может меняться (из-за одноразовой привязки), вы не можете увидеть разницу до и после копии. Я все еще ищу решение для вас и некоторые доказательства того, что я говорю. – Blackhole

ответ

-1

Вот что я нашел в угловом documentation:
Выражение, которое начинается с :: считается выражением одноразовая. Одноразовые выражения останавливают пересчет, как только они стабильны.

Это эффективно означает, что при визуализации страницы и выполнении ng-repeat итерация выполняется правильно, а значения печатаются в правильном порядке. После завершения ng-repeat значение, присвоенное {{:: item}}, равно 'D'. Если изменяется длина коллекции, ng-repeat добавит новый элемент, но этот элемент будет D каждый раз, потому что {{:: item}} разрешает D. Это происходит независимо от правильной работы функции копирования и добавления правильного элемент коллекции. Итак, ваша коллекция больше не является источником истины. Это то, что одноразовое обязательство означает, что вы больше не подключены к источнику. Вот полный текст: Почему эта функция Основная цель одноразового выражения привязки - предоставить способ создания привязки, которая получает отмененную регистрацию и освобождает ресурсы после стабилизации привязки. Уменьшение количества наблюдаемых выражений делает цикл дайджеста более быстрым и позволяет одновременно отображать больше информации.

Почему эта функция

Основные целью выражения связывания единовременного является обеспечить способ для создать привязку, которая получает и освобождает с учетом ресурсов, как только связывание стабилизируются. Уменьшение числа выражений, наблюдаемых , делает цикл сбора данных более быстрым и позволяет одновременно отображать .

Алгоритм стабилизации Значение

Одноразовый выражения привязки сохранит значение выражения в конце цикла дайджеста тех пор, пока это значение не определено. Если значение выражения установлено в цикле дайджеста и позже, в том же цикле дайджеста установлено значение undefined, то выражение не выполняется и будет наблюдаться.

  1. Учитывая выражение, которое начинается с ::, когда переваривать цикл вводится и выражение грязно-проверено, хранить значение как V
  2. Если V не определено, отметьте результат выражения как стабильная и запланировать задачу дерегистрировать часы для этого выражения, когда мы выходим из цикла переваривать
  3. процесс петли переваривать как обычный
  4. когда переваривать цикл закончен, и все значения осели, процесс очереди заданий часов дерегистрационных. Для каждого вахты должно быть снято с учета, проверьте, не оценивает ли оно значение, которое не является неопределенным. Если это так, отмените регистрацию часов. В противном случае, держать грязных проверки часов в будущем переваривать петлю, следуя же алгоритм, начиная с шага 1
+0

Это решение не в порядке, так как кнопка копирования выполняет итерацию. Я не хочу этого. –

+0

Перед тем как опробовать, пожалуйста, проверьте свой собственный код.Я просто играл со своей скрипкой. В любом случае, пожалуйста, см. Мой обновленный ответ. –

+0

Я, кстати, не ответил на ваш ответ ... –

0

Я думаю, что ответ Sidharth Panwar правилен по большей части, за исключением одного.

Пояснение: Начальное состояние списка является ['A', 'B', 'C', 'D'] и первые 4 элементы один раз ограничена (т.е. изменение их стоимости не отразится на пользовательском интерфейсе), но при любом случае, если вход был в диапазоне 0-3, в список добавлен новый элемент, а последний символ 'D' в списке переносится на пятое место. Поскольку элемент на 5-м месте в списке не ограничен в один раз, в списке отображается новый D.

Трассировка:

  1. Исходное состояние: ['A', 'B', 'C', 'D']
  2. дубликатом 'A', давая 0 в качестве вклада в текстовое поле
  3. Новое состояние: ['A','A','B', 'C','D']

Так как первые 4 элемента ограничены одним ограничением, список не изменит значение, которое было связано в первом цикле дайджеста, однако, поскольку новый элемент найден на пятом месте, он должен сделать однократную привязку для этого нового элемента.

Добавление любого элемента до или в месте D в списке приведет к сдвигу последнего элемента на одно место, поскольку этот новый элемент не связан, создается однократная привязка. Но в этом случае кажется, что новый элемент всегда будет 'D', потому что он находится в хвосте списка.

Надеюсь, это поможет!

+0

Я думаю, что ваше объяснение имеет больше смысла, но по-прежнему не отвечает на мой вопрос; в моем коде я глубоко копирую $ scope.items [parseInt (item)], который указывает на правильный элемент в то время. Кроме того, когда я заполняю «X» и нажимаю кнопку «Ädd», в конце добавляется правильное значение. По-прежнему остается загадкой, почему это не работает! –

Смежные вопросы