2016-06-13 12 views
1

Ich bin eine editierbare Baumstruktur mit Knockout sortierbar machen und fand dieses große Beispiel: http://jsfiddle.net/rniemeyer/LqttfKnockout sortierbar macht Duplikate (Herstellung einer Baumstruktur)

Das funktioniert gut, aber ich habe eine Liste der Root-Knoten, damit ich das geändert Die Wurzelknotenbindung ist auch eine sortierbare Liste von Baumelementen. Fiddle: http://jsfiddle.net/yyqnhngm

Die neue Vorlage Markup sieht wie folgt aus (beachten Sie, dass die Wurzel ul eine sortable Bindung und keine template wie im Original):

<script id="nodeTmpl" type="text/html"> 
    <li> 
     <a href="#" data-bind="text: name"></a> 
     <div> 
      <ul data-bind="sortable: { template: 'nodeTmpl', data: $data.children }"></ul>    
     </div> 
    </li> 
</script> 

<ul data-bind="sortable: { template: 'nodeTmpl', data: root }"></ul> 

Wenn Sie B in A ziehen, dann B wird kopiert werden statt in A bewegt. Das ist das Problem, ich suche nach einer Ursache für und die Lösung für. Mein erster Gedanke ist, dass sortierbar denkt, dass der Artikel zur gleichen Zeit in beide Listen gezogen wird, vielleicht wegen eines Markup-/HTML-Problems, aber ich kann nicht sehen, wie.

Hinweis: Ich weiß, ich könnte einfach alle Elemente in einen Grundton einfügen, aber das macht für meine Zwecke keinen Sinn.

+1

Teilt die Bibliothek benötigen, um die Elemente in einem 'observableArray' sein zu sortieren? Wenn ich das 'root' Array zu einem' ko.observableArray' ändere, funktionieren alle _seems_ einwandfrei. Aus der Dokumentation: "knockout-sortable ist eine Bindung für Knockout.js, die entwickelt wurde, um ** observableArrays ** mit der sortierbaren Funktionalität von jQuery UI zu verbinden" – user3297291

+0

Ich denke, Sie haben Recht, das scheint es zu sein. Wenn Sie eine Antwort einreichen können, werde ich es als Lösung markieren :) – altschuler

Antwort

1

Es scheint mir, dass es keine Unterstützung für "normale" Arrays gibt. Wenn Sie das Array in Ihrem Ansichtsmodell in eine observableArray ändern, erhalten Sie die erforderlichen Eigenschaften. Ie:

ko.applyBindings({ 
    root: ko.observableArray([ 
    new TreeItem("A", []), 
    new TreeItem("B", []) 
    ]) 
}); 

als Referenz:

Gemäß der knockout-sortable readme(emphasis Mine):

knockout-sortierbar eine Bindung für Knockout.js ausgelegt ist observableArrays verbinden mit Die sortierbare Funktionalität von jQuery UI.

Ich habe auch versucht, durch die Quelle zu gehen, um zu erklären, was genau falsch lief, aber konnte die genaue Ursache nicht finden. Ich habe einen Ausschnitt gefunden, der zumindest die Gedanken des Autors zu erklären scheint.

Der Code zeigt, dass das Standardverhalten des Plugins die Methode splice verwendet, um ein Element zwischen Arrays zu verschieben. Dies könnte erklären, warum Ihr Beispiel keine Ausnahme ausgelöst hat: Sowohl Array.prototype als auch ko.observableArray haben eine splice Methode; beide nehmen ähnliche Argumente an.

Der letzte Kommentar im Codeblock erklärt, dass targetParent und sourceParent erwartet werden, dass sie beobachtbar sind.

if (!sortable.hasOwnProperty("strategyMove") || sortable.strategyMove === false) { 
    //do the actual move 
    if (targetIndex >= 0) { 
    if (sourceParent) { 
     sourceParent.splice(sourceIndex, 1); 

     //if using deferred updates plugin, force updates 
     if (ko.processAllDeferredBindingUpdates) { 
     ko.processAllDeferredBindingUpdates(); 
     } 
    } 

    targetParent.splice(targetIndex, 0, item); 
    } 

    //rendering is handled by manipulating the observableArray; ignore dropped element 
    dataSet(el, ITEMKEY, null); 
} 

Quelle: https://github.com/rniemeyer/knockout-sortable/blob/master/src/knockout-sortable.js#L250