Ziehen und Drop -sortierbarer NG: Wiederholungen in AngularJs?
-
28-10-2019 - |
Frage
Ist es überhaupt einfach zu bedienen jQuery.sortable
an ng-repeat
Elemente in AngularJs?
Es wäre fantastisch, wenn das Neubestehen der Elemente diese Bestellung wieder in das Quellarray ausbreitet. Ich fürchte, die beiden Systeme würden jedoch kämpfen. Gibt es einen besseren Weg, dies zu tun?
Lösung
Angular UI hat eine sortierbare Richtlinie,Klicken Sie hier für die Demo
Code bei UI-sortierbar, Verwendungszweck:
<ul ui-sortable ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
Andere Tipps
Ich habe versucht, dasselbe zu tun und die folgende Lösung zu finden:
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);
}
}
});
};
});
So verwendet:
<ol id="todoList" my:sortable="todos" my:onsort="onSort()">
Es scheint ziemlich gut zu funktionieren. Der Trick besteht darin, die DOM -Manipulation, die durch sortierbar gemacht wurde, vor der Aktualisierung des Modells rückgängig zu machen. Andernfalls wird Agular aus dem DOM deynchronisiert.
Die Benachrichtigung über die Änderungen funktioniert über den Ausdruck von My: Onsort, der die Controller -Methoden aufrufen kann.
Ich habe eine JSFIDDLE erstellt, die auf dem Angular Todo -Tutorial basiert, um zu zeigen, wie es funktioniert: http://jsfiddle.net/m8ynr/180/
So mache ich es mit einem eckigen V0.10.6. Hier ist der 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();
}
});
};
});
Hier ist meine Implementierung von sortierbarer angular.js Richtlinie ohne jQuery.ui:
Sie können sich für eine leichte NG-sortierbare Richtlinie entscheiden und nicht JQuery verwendet. Hier ist Link NG-sortierbare Drag & Drop-Elemente