Подтвердить что ты не робот

Angularjs - ngRepeat с ngInit - ngRepeat не обновляет отображаемое значение

У меня есть массив, который отображается с помощью ngRepeater, но с этой директивой я использую директиву ngInit, которая выполняет функцию, которая должна возвращать объект для отображения. Все работает отлично, но когда я добавил кнопку "Создать", где я добавляю новое значение в массив, тогда функция "SetPreview" выполняется только один раз, я думаю, что функция должна выполняться в зависимости от величины значения массива. Как я могу это сделать?

интерфейс:

<body ng-app>

  <ul ng-controller="PhoneListCtrl">
      <button ng-click="add()">Add</button>
    <li ng-repeat="phone in phones" ng-init="displayedQuestion=SetPreview(phone);">
      {{displayedQuestion.name}}
      <p>{{displayedQuestion.snippet}}</p>
    </li>
  </ul>
</body>

Контроллер:

function PhoneListCtrl($scope) {
  $scope.phones = [
    {"name": "Nexus S",
     "snippet": "Fast just got faster with Nexus S."},
    {"name": "Motorola XOOM™ with Wi-Fi",
     "snippet": "The Next, Next Generation tablet."},
    {"name": "MOTOROLA XOOM™",
     "snippet": "The Next, Next Generation tablet."}
  ];

    $scope.add = function(){
        this.phones.push({name:'1', snippet:'n'});
    };        
    $scope.SetPreview = function(phone)
    {
        //here logic which can take object from diffrent location
        console.log(phone);
        return phone;
    };
}

Пример здесь - jsfiddle

Изменить:
Вот более сложный пример: → Теперь коллекция телефонов пуста, когда вы нажимаете кнопку "Добавить", новый элемент добавляется и устанавливается как редактируемый (вы может изменять значение в текстовом поле), а когда ngRender выполняется, функция SetPreview возвращает редактируемый объект (его работа, например, просмотр). Теперь попробуйте нажать кнопку "Добавить" еще раз, и, поскольку вы можете увидеть, что редактируемое значение первого элемента все еще представлено пользователю, но я хочу обновить весь ng-повторитель.

4b9b3361

Ответ 1

Вы используете функцию производительности Angular.

По существу Angular может видеть, что элемент в массиве (например, "A" ) - это одна и та же ссылка на объект, поэтому он больше не вызывает ng-init. Это эффективно. Даже если вы объединили старый список в новый список, Angular увидит, что это та же ссылка.

Если вместо этого вы создаете новый объект с теми же значениями, что и старый объект, он имеет другую ссылку и Angular повторно вводит его: Плохой пример, который делает то, что вы ищете: http://jsfiddle.net/fqnKt/37/

$scope.add = function(item) {
    var newItems = [];
    angular.forEach($scope.items, function(obj){
        this.push({val:obj.val});
    },newItems)

    newItems.push({val:item})
    $scope.items = newItems;
};

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

Ответ 2

Я обнаружил, что вы можете просто заменить ng-init выражением angular {{}} в скрытом блоке:

<body ng-app>

<ul ng-controller="PhoneListCtrl">
    <button ng-click="add()">Add</button>
    <li ng-repeat="phone in phones">
      <span style="display: none">{{displayedQuestion=SetPreview(phone)}}</span>
      {{displayedQuestion.name}}
      <p>{{displayedQuestion.snippet}}</p>
    </li>
  </ul>
</body>

Ответ 3

Если у вас есть ngInit в элементе и ngRepeat в потомке, ngInit будет запускаться только один раз.

Чтобы исправить это, добавьте ngRepeat к элементу с ngInit, с выражением, которое повторяется один раз и зависит от того же массива (и других зависимостей).

Например:

ng-repeat="_ in [ products ]" ng-init="total = 0"