web-dev-qa-db-fra.com

Faites glisser et déposez le fichier triable: répéter dans AngularJS?

Est-il facile d'utiliserjQuery.sortableonng-repeatelements dans AngularJS? 


Ce serait génial si le ré-ordonnancement des éléments renvoyait automatiquement cet ordre dans le tableau source. J'ai bien peur que les deux systèmes se battent bien. Y a-t-il une meilleure manière de faire cela?

61
Nick Retallack

L'interface utilisateur angulaire a une directive triable, Cliquez ici pour une démonstration

Code situé à ui-sortable , utilisation:

<ul ui-sortable ng-model="items">
  <li ng-repeat="item in items">{{ item }}</li>
</ul>
76
Guillaume86

J'ai essayé de faire la même chose et ai proposé la solution suivante:

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);
                }
            }
        });
    };
});

Utilisé comme ceci: 

<ol id="todoList" my:sortable="todos" my:onsort="onSort()">

Cela semble fonctionner assez bien. L'astuce consiste à annuler la manipulation du DOM effectuée par sortable avant la mise à jour du modèle, sinon agular est désynchronisé à partir du DOM.

La notification des modifications fonctionne via l'expression my: onsort qui peut appeler les méthodes du contrôleur.

J'ai créé un JsFiddle basé sur le tutoriel angulaire todo pour montrer comment cela fonctionne: http://jsfiddle.net/M8YnR/180/

12
Manuel Woelker

Voici comment je le fais avec v0.10.6 angulaire. Voici le 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();
            }
        });
    };
});
10
respectTheCode

Voici mon implémentation de la directive sortable Angular.js sans jquery.ui:

5

vous pouvez opter pour la directive ng-sortable qui est légère et qui n’utilise pas jquery. voici les éléments link drag-drop ng-sortable

Démo pour ng-sortable

0
Dheeraj Nalawade