Javascript 在 AngularJS 中拖放可排序的 ng:repeats?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7354992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Drag and drop sortable ng:repeats in AngularJS?
提问by Nick Retallack
Is it at all easy to use jQuery.sortable
on ng-repeat
elements in AngularJS?
在 AngularJS 中的元素上使用jQuery.sortable
起来容易ng-repeat
吗?
It would be awesome if re-ordering the items automatically propagated that ordering back into the source array. I'm afraid the two systems would fight though. Is there a better way to do this?
如果重新排序项目会自动将该排序传播回源数组,那就太棒了。恐怕这两个系统会打架。有一个更好的方法吗?
回答by Guillaume86
Angular UI has a sortable directive,Click Here for Demo
Angular UI 有一个可排序的指令,点击这里查看演示
Code located at ui-sortable, usage:
代码位于ui-sortable,用法:
<ul ui-sortable ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
回答by Manuel Woelker
I tried to do the same and came up with the following solution:
我尝试做同样的事情,并提出了以下解决方案:
angular.directive("my:sortable", function(expression, compiledElement){
return function(linkElement){
var scope = this;
linkElement.sortable(
{
placeholder: "ui-state-highlight",
opacity: 0.8,
update: function(event, ui) {
var model = scope.$tryEval(expression);
var newModel = [];
var items = [];
linkElement.children().each(function() {
var item = $(this);
// get old item index
var oldIndex = item.attr("ng:repeat-index");
if(oldIndex) {
// new model in new order
newModel.push(model[oldIndex]);
// items in original order
items[oldIndex] = item;
// and remove
item.detach();
}
});
// restore original dom order, so angular does not get confused
linkElement.append.apply(linkElement,items);
// clear old list
model.length = 0;
// add elements in new order
model.push.apply(model, newModel);
// presto
scope.$eval();
// Notify event handler
var onSortExpression = linkElement.attr("my:onsort");
if(onSortExpression) {
scope.$tryEval(onSortExpression, linkElement);
}
}
});
};
});
Used like this:
像这样使用:
<ol id="todoList" my:sortable="todos" my:onsort="onSort()">
It seems to work fairly well. The trick is to undo the DOM manipulation made by sortable before updating the model, otherwise agular gets desynchronized from the DOM.
它似乎工作得很好。诀窍是在更新模型之前撤消 sortable 所做的 DOM 操作,否则 angular 会与 DOM 不同步。
Notification of the changes works via the my:onsort expression which can call the controller methods.
更改通知通过 my:onsort 表达式工作,该表达式可以调用控制器方法。
I created a JsFiddle based on the angular todo tutorial to shows how it works: http://jsfiddle.net/M8YnR/180/
我根据 angular todo 教程创建了一个 JsFiddle 来展示它是如何工作的:http: //jsfiddle.net/M8YnR/180/
回答by respectTheCode
This is how I am doing it with angular v0.10.6. Here is the jsfiddle
这就是我使用 angular v0.10.6 的方式。这是jsfiddle
angular.directive("my:sortable", function(expression, compiledElement){
// add my:sortable-index to children so we know the index in the model
compiledElement.children().attr("my:sortable-index","{{$index}}");
return function(linkElement){
var scope = this;
linkElement.sortable({
placeholder: "placeholder",
opacity: 0.8,
axis: "y",
update: function(event, ui) {
// get model
var model = scope.$apply(expression);
// remember its length
var modelLength = model.length;
// rember html nodes
var items = [];
// loop through items in new order
linkElement.children().each(function(index) {
var item = $(this);
// get old item index
var oldIndex = parseInt(item.attr("my:sortable-index"), 10);
// add item to the end of model
model.push(model[oldIndex]);
if(item.attr("my:sortable-index")) {
// items in original order to restore dom
items[oldIndex] = item;
// and remove item from dom
item.detach();
}
});
model.splice(0, modelLength);
// restore original dom order, so angular does not get confused
linkElement.append.apply(linkElement,items);
// notify angular of the change
scope.$digest();
}
});
};
});
回答by Sebastien Chartier
Here's my implementation of sortable Angular.js directive without jquery.ui :
这是我在没有 jquery.ui 的情况下对可排序的 Angular.js 指令的实现:
回答by Dheeraj Nalawade
you can go for ng-sortable directive which is lightweight and it does not uses jquery. here is link ng-sortable drag and drop elements
你可以选择轻量级的 ng-sortable 指令,它不使用 jquery。这是链接ng-sortable 拖放元素