Angular.js: возможно ли повторно отображать повторы ng на основе существующих данных области видимости?

На мой взгляд, у меня есть куча связанных списков ul, которые используют директиву jQuery UI: Sortable для облегчения перетаскивания и изменения порядка элементов списка.

Изменения, которые я делаю с помощью перетаскивания пользовательского интерфейса jQuery, я применяю к $scope с помощью функции $apply, эта часть работает…

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

Пользователь имеет возможность:

  1. заполните форму и продолжите, после чего вызов $apply сохранит данные в $scope
  2. нажмите кнопку отмены, которая вместо вызова $apply для сохранения информации должна отменить последнее взаимодействие перетаскивания, эффективно «перерисовывая» все мои списки, чтобы отразить данные, которые все еще находятся в $scope на этом этапе (поскольку последнее перетаскивание было на это еще не повлияло).

Эффект этой кнопки «отмена» фактически возвращает все к точке, прежде чем пользователь взял элемент списка и перетащил его в другой список.

Как я могу принудительно «обновить» или «перерендерить» мои ng-repeat, чтобы они визуально обновлялись и снова отображали текущие данные $scope?


person Jannis    schedule 26.09.2012    source источник
comment
Обычно достаточно просто изменить модель данных ($scope), если это делается внутри AngularJS. Если это делается снаружи, вызов $scope.$apply() должен вызвать обновление/обновление. В конце ваших манипуляций с отменой вы вызываете $scope.$apply() или оборачиваете свои изменения в $scope.$apply(function() { ... changes here... }) ?   -  person Mark Rajcok    schedule 26.09.2012
comment
Я действительно вызываю $scope.apply() из директивы на основе jQuery, но, похоже, это не приводит к перезагрузке/повторному рендерингу существующих данных. Вероятно, потому что Angular думает, что все точно так же, не зная о том, что я проделал манипуляцию с DOM, не сказав ему об этом. Итак, что мне действительно нужно, так это просто вызов типа «принудительное обновление», где Angular независимо от состояния $scope просто принудительно обновляет отображаемые данные.   -  person Jannis    schedule 26.09.2012
comment
Что ж, как возможный обходной путь, что, если вы удалите перетаскиваемый элемент из $scope внутри вашего вызова $scope.$apply() -- Angular должен увидеть это и выполнить повторную визуализацию -- затем на следующей строке (все еще внутри вашего $scope. $apply()) добавьте его снова, используя $timeout(): $timeout( function(){ ...add removed item back to $scope here... }); Манипуляции с $scope, которые вы выполняете в функции $timeout, должны привести к повторному рендерингу.   -  person Mark Rajcok    schedule 03.10.2012
comment
Хорошая идея, немного жаль, что приходится дважды перерисовывать, но да, это может сработать. Попробую позже, спасибо за комментарий.   -  person Jannis    schedule 03.10.2012


Ответы (1)


Когда пользователь начинает заполнять форму, я бы установил

$scope.oldData = angular.copy($scope.data);

Затем позвольте пользователю редактировать $scope.data, используя форму, как ему нравится.

Затем, если пользователь нажмет кнопку отмены, просто установите $scope.data = $scope.oldData.

person Andrew Joslin    schedule 05.11.2012
comment
Я использовал этот способ, но мне нужно было дважды вызвать $apply; scope.oldData = angular.copy(scope.irs); область.irs.длина = 0; область. $ применить(); scope.irs = scope.oldData; область. $ применить(); - person Aladdin Mhemed; 01.03.2013
comment
Это отличное решение. Это помогло мне вызвать повторную визуализацию ng-repeat, когда сами данные не изменились, но должны были принудительно повторно отображаться. Я сделал только $scope.data[0] = angular.copy($scope.data[0]); вместо копирования всего массива. Было бы неплохо узнать, есть ли функция angularjs для этого триггера повторного рендеринга; - person Daniel F; 21.09.2013
comment
По умолчанию angular будет отслеживать, нужно ли повторно отображать элемент ng-repeat, помещая переменную $$hashKey в каждый объект в повторителе. Если $$hashKey изменяется в одном из индексов, он перерисовывает это. HashKey может измениться, если элемент перемещается в массиве, удаляется или добавляется новый. Вы можете указать angular, какое свойство отслеживать, чтобы увидеть, должно ли оно повторно отображаться, выполнив ng-repeat="item in items track by item.id" или тому подобное - тогда, если item.id изменится в индексе, оно будет повторно отображаться. - person Andrew Joslin; 24.09.2013