AngularJS ng-repeat重新渲染 [英] AngularJS ng-repeat rerender
问题描述
我正在使用AngularJS构建一个简单的应用程序。该应用程序对服务器进行异步AJAX调用,服务器返回如下数组:
{
段落: [
{content:content one},
{content:cnt two},
{content:random three},
{content:last one yeeaah}
]
}
所以我将此内容设置为StorageService工厂通过我的set方法。这里一切都很好。
我正在使用 ng-repeat
来渲染结果, JQuery UI可排序
能够更改元素的顺序。交换项目时,我的脚本正在调用StorageService.swap方法,并且StorageService中的元素顺序已更新, BUT ng-repeat不会重新发布更改,但如果我删除/添加或更改内容它的工作。我如何强制角度重新渲染ng-repeat?
= JSFIDDLE =
,显示尝试解决问题但仍有问题)。这些问题已在 Angular UI Sortable 。所以一个好的前进道路可能就是切换到这个。
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 =
= 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;
}
};
});
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.
这篇关于AngularJS ng-repeat重新渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!