Pregunta

¿Es fácil de usar? jQuery.sortable en ng-repeat elementos en angularjs?


Sería increíble si el reordenamiento de los elementos se propagó automáticamente ese pedido de nuevo en la matriz de origen. Sin embargo, me temo que los dos sistemas pelearían. ¿Hay una mejor manera de hacer esto?

¿Fue útil?

Solución

Angular UI tiene una directiva ordenable,Haga clic aquí para la demostración

Código ubicado en fundamental, uso:

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

Otros consejos

Traté de hacer lo mismo y se me ocurrió la siguiente solución:

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

Usado así:

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

Parece funcionar bastante bien. El truco es deshacer la manipulación DOM realizada por SAPTABLE antes de actualizar el modelo, de lo contrario, Agular se desincroniza del DOM.

La notificación de los cambios funciona a través de la expresión my: onsort que puede llamar a los métodos del controlador.

Creé un jsfiddle basado en el tutorial Angular TODO para mostrar cómo funciona: http://jsfiddle.net/m8ynr/180/

Así es como lo estoy haciendo con Angular V0.10.6. Aquí está el 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();
            }
        });
    };
});

Aquí está mi implementación de la directiva de Orgular.js Sortable sin jQuery.ui:

Puede optar por la directiva Ng-sortable que es liviana y no usa jQuery. Aquí está el enlace Elementos de arrastre y caída de arrastre de Ng

Demostración para ng-sortable

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top