在AngularJS中拖放可排序的ng:重复?
Posted
技术标签:
【中文标题】在AngularJS中拖放可排序的ng:重复?【英文标题】:Drag and drop sortable ng:repeats in AngularJS? 【发布时间】:2011-11-13 09:01:07 【问题描述】:在 AngularJS 中的 ng-repeat
元素上使用 jQuery.sortable
是否容易?
如果重新排序项目会自动将该排序传播回源数组,那就太棒了。恐怕这两个系统会打架。有没有更好的方法来做到这一点?
【问题讨论】:
您是否可以更新 Angular js 当前版本的 js fiddle 代码,即 Angular js 1.0.1。我尝试通过根据我的要求将 angular js 的版本更改为 1.0.1 来在 jsfiddle 上运行示例,但随后代码中断并且不起作用。请帮忙。谢谢! 我同意这一点。还在寻找 1.0.1 的工作示例 :-) 找到了这个,在 1.0.1 中工作 - jsfiddle.net/007design/KHqbM 我创建了一个教程,介绍如何结合 JQuery UI 执行此操作。使用单个指令很容易做到。解释和例子可以在这里找到:smartjava.org/content/drag-and-drop-angularjs-using-jquery-ui 【参考方案1】:Angular UI 有一个可排序的指令,Click Here for Demo
代码位于ui-sortable,用法:
<ul ui-sortable ng-model="items" ui-sortable-update="sorted">
<li ng-repeat="item in items track by $index" id="$index"> item </li>
</ul>
$scope.sorted = (event, ui) => console.log(ui.item[0].getAttribute('id'))
【讨论】:
请注意,您应该添加ng-model
和ui:sortable
:<ul ui:sortable ng:model="list">
控制台有错误吗?在我的 chrome/windows 7 中工作,您可以尝试更新库(jquery/jqueryUI/angular/angularUI),看看它是否解决了您的问题...
jsfiddle 示例似乎不能可靠地工作。没有错误,但订单间歇性地变得不同步。在 Firefox 和 chrome 中尝试过
知道如何在没有 jQuery 的情况下实现这一目标吗?
@Kugel 你有没有尝试过 angular-ui sortable 的最后一个版本?以角度发展的速度,演示很快就会过时:github.com/angular-ui/ui-sortable【参考方案2】:
我尝试做同样的事情并想出了以下解决方案:
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);
);
;
);
这样使用:
<ol id="todoList" my:sortable="todos" my:onsort="onSort()">
它似乎工作得很好。诀窍是在更新模型之前撤消 sortable 所做的 DOM 操作,否则 angular 会与 DOM 不同步。
更改通知通过可调用控制器方法的 my:onsort 表达式工作。
我根据 angular todo 教程创建了一个 JsFiddle 来展示它是如何工作的:http://jsfiddle.net/M8YnR/180/
【讨论】:
【参考方案3】:这就是我使用 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();
);
;
);
【讨论】:
我最终只使用了 SlickGrid,但我相信你的话,这是可行的。 此解决方案需要注意的一点是,它很可能无法像 v1.x 那样工作。调整这个应该不难,但我还没有开始更新我的所有代码。 @respectTheCode 您是否重构了代码以使用最新的 AngularJS 版本(v1.0.1)?我一辈子都找不到可靠的 1.0.1 工作版本...... @Greg 我们现在正在使用 Angular-UI 的 UI-Sortable,效果很好。 github.com/angular-ui/ui-sortable【参考方案4】:这是我在没有 jquery.ui 的情况下实现可排序的 Angular.js 指令:
https://github.com/schartier/angular-sortable【讨论】:
【参考方案5】:您可以选择轻量级且不使用 jquery 的 ng-sortable 指令。这是链接ng-sortable drag and drop elements
Demo for ng-sortable
【讨论】:
以上是关于在AngularJS中拖放可排序的ng:重复?的主要内容,如果未能解决你的问题,请参考以下文章