AngularJS ng-repeat rerender

匿名 (未验证) 提交于 2019-12-03 00:54:02

问题:

I'm building a simple app with AngularJS. The app make a async AJAX call to the server and the server returns an array like this:

{     paragraphs: [         {content: "content one"},         {content: "cnt two"},         {content: "random three"},         {content: "last one yeeaah"}     ] } 

So I'm setting this content to the StorageService factory via my set method. Everything is fine here.

I'm using ng-repeat to render the results and JQuery UI sortable to be able to change the order of the elements. When an item is swapped my script is calling the StorageService.swap method and the element order in StorageService is updated, BUT ng-repeat isn't rerendering the change, but if I remove/add or change the content it's working. How I can force the angular to rerender the ng-repeat?

= JSFIDDLE =

http://jsfiddle.net/6Jzx4/3/

= Example =

When a swap occurs the ng-repeat should be rerendered, so the IDs are consecutive

= Code =

HTML

<div ng-controller="Test" sortable>     <div ng-repeat="item in data().paragraphs" class="box slide_content" id="{{$index}}">          {{item.content}}, ID: {{$index}}     </div>      <input type="button" ng-click="add()" value="Add"> </div> 

JS

var App = angular.module("MyApp", []);  App.controller("Test", function($scope, StorageService) {     StorageService.set({         paragraphs: [             {content: "content one"},             {content: "cnt two"},             {content: "random three"},             {content: "last one yeeaah"}         ]     });      $scope.data = StorageService.get;      $scope.add = StorageService.add; });  App.directive("sortable", function(StorageService) {     return {         link: function(scope, element, attrs) {             $(element[0]).sortable({                 cancel: ".disabled",                 items: "> .slide_content:not(.disabled)",                 start: function(e, t) {                     t.item.data("start_pos", t.item.index());                 },                 stop: function(e, t) {                     var r = t.item.data("start_pos");                     if (r != t.item.index()) {                                     StorageService.sort($(this).sortable("toArray"));                     }                 }             });         }     }; });  App.factory('StorageService', function() {     var output = {};      return {         set: function(data) {             angular.copy(data, output);             return output;         },         get: function() {             return output;         },         add: function() {             output.paragraphs.push({                 content: 'Content'             });         },         sort: function(order) {             var localOutput = [];              for (var j in order) {                 var id = parseInt(order[j]);                 localOutput.push(output.paragraphs[id]);             }              console.log('new order', localOutput);              output.paragraphs = localOutput;             return output;         }     }; }); 

回答1:

Angular doesn't know you've changed the array. Executing your sort inside a scope.$apply() will address that.

Note that I've added a that variable since this changes meaning inside the apply.

var that = this; scope.$apply(function() {       StorageService.sort($(that).sortable("toArray")); } 

But that fix uncovers other problems that appear to be caused by the interaction between the jQuery sortable and Angular (here's a fiddle that shows an attempt at resolving the problems but still has issues). These issues have been solved in Angular UI Sortable. So a good path forward may be to switch to this.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!