Странное поведение Angular 1.3 при копировании элемента в NG-повтор

0

Я придумал очень странное поведение в 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

Я думаю, что ответ Сидхарта Панвара по большей части является правильным, кроме одного.

Объяснение: Исходным состоянием списка является ['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», в конце добавляется правильное значение. До сих пор остается загадкой, почему это не работает!
-1

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

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

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

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

Алгоритм стабилизации стоимости

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню