Frage

I've an ng-repeat in my angular template which needs to be sortable. I'm using jQuery-ui's Sortable to implement it.

The JS:

$scope.data = [{"key":123,"val":"a"},
{"key":124,"val":"b"},
{"key":125,"val":"c"}];

$(".sortable").sortable();

The template:

<div class="sortable"> 
    <div ng-repeat="sub in data" >
        {{sub.key}}
    </div>
</div>

This works perfectly fine, and I can drag and drop the elements. However, when a ng-repeat is nested within another, it doesn't work; I'm unable to drag anything. On using Chrome inspector, I see that the class 'ui-sortable' is not added to any element at all.

The JS:

$scope.subJson = [{"name":"MS1","slides":[{"title":"Title1"},{"title":"Title2"}]},{"name":"MS2","slides":[{"title":"Title3"},{"title":"Title4"}]}];

$(".sortable").sortable();

The template:

<div> 
    <div ng-repeat="sub in subJson" >
        {{sub.name}}
        <div class="sortable">
            <div ng-repeat="slide in sub.slides" >
                {{slide.title}}
            </div>
        </div>
    </div>
</div>

Why does this happen? Is there a solution?

War es hilfreich?

Lösung

Maybe this problem lies in the execution time of $('.sortable').sortable(). Sortable finds elements with classname sortable immediately after the controller is set up.

At that time the ng-repeat has not been initiated, so the $('.sortable') finds no element. In the js fiddle below, the output in console shows this problem. http://jsfiddle.net/Q5FWt/439/

A quick dirty fix is put $('.sortable').sortable() in a setTimeout. However, manipulating dom element is never an angular way! A desirable way to achieve this is to construct a directive, or use a angular-ui plugin like this, https://github.com/angular-ui/ui-sortable

Andere Tipps

Sortable needs to reload the object to control.

Put the $(".sortable").sortable(); inside a function and then call that function in the item row of the list.

For example:

function init() {
    $(".sortable").sortable();
}

then in your html:

<div> 
<div ng-repeat="sub in subJson" >
    {{sub.name}}
    <div class="sortable">
        <div ng-repeat="slide in sub.slides" >
            <div class="layer-draggable" 
              ng-mousedown="init()">
                {{slide.title}}
          </div>
        </div>
    </div>
</div>

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top