2016-03-23 8 views
4

Mein Ziel ist es, Benutzern das Sortieren einer Befehlsliste zu ermöglichen. Ich entwickle meine Anwendung mit Angular2/Typescript.JQueryUI Sortierfunktion funktioniert nicht, wenn eine benutzerdefinierte Komponente mit Angular2 verwendet wird

Also suchte ich nach angular2 basierten Bibliotheken, die sortierbare Funktionalität ähnlich wie JQueryUI Sortierbar, aber nicht viel zu finden.

Ich stieß auf this SO Post, die demonstriert, wie man JQuery mit angular2 integriert. Mit dem Plunk in einer der Lösungen für diesen Beitrag könnte ich ein sortierbares Verhalten mit angular2 entwickeln. Siehe hierzu plunk. Dies funktioniert wie erwartet.

@Component({ 
    selector: 'my-app', 
    directives: [SMSortable], 
    providers: [], 
    template: ` 
    <div> 
     <p>This is a list that can be sorted </p> 
     <div sm-sortable> 
     <p>Item 1</p> 
     <p>Item 2</p> 
     <p>Item 3</p> 
     </div> 
    </div> 
    ` 
}) 
export class App { 
    constructor() { 
    this.name = 'Angular2' 
    } 
} 

Die Idee war, eine Richtlinie zu definieren, die das sortierbare Verhalten auf das native Element mit jQueryUI sortierbar() API gelten würde. Und dann verwenden Sie die Direktive in der Vorlage der Komponente.

@Directive({ 
    selector: "[sm-sortable]" 
}) 
export class SMSortable{ 

    constructor(el: ElementRef) { 
     jQuery(el.nativeElement).sortable({ 
       start: function(event, ui) { 
        console.log("Old position: " + ui.item.index()); 
       }, 
       stop: function(event, ui) { 
        console.log("New position: " + ui.item.index()); 
       } 
     }); 
    } 
} 

Das funktioniert gut, wenn die Vorlage der Komponente alle nativen Elemente. Wenn meine Vorlage jedoch benutzerdefinierte angular2-Komponenten enthält, funktioniert diese nicht mehr.

Siehe hierzu not-working plunk.

@Component ({ 
    selector: 'sm-cmd', 
    template: '<ng-content></ng-content>' 
}) 
export class SMCommand { 

} 

@Component({ 
    selector: 'my-app', 
    directives: [SMSortable, SMCommand], 
    providers: [], 
    template: ` 
    <div> 
     <p>This is a list that can be sorted </p> 
     <div sm-sortable> 
     <sm-cmd><p>Item 1</p></sm-cmd> 
     <sm-cmd><p>Item 2</p></sm-cmd> 
     <sm-cmd><p>Item 3</p></sm-cmd> 
     </div> 
    </div> 
    ` 
}) 
export class App { 

} 

In diesem Fall: Ich kann den Artikel ziehen, aber nicht in der Lage, es zu löschen. Das verschobene Objekt wird an seinen ursprünglichen Speicherort zurückgesetzt. Ich habe console.log hinzugefügt, um den Elementindex beim Starten und Stoppen des Ereignisses während des Sortierens anzuzeigen. Der Wert bleibt gleich.

Ich bin nicht in der Lage, weiter zu debuggen. Könnte jemand dazu etwas beitragen?

+0

Beitrag nicht arbeit plunkr. – dfsq

+0

nicht funktionierender Plotter funktioniert tatsächlich - falsche Verbindung? –

+0

Ja arbeitet nicht in der Tat. – micronyks

Antwort

5

Das Problem ist eigentlich sehr einfach: Da Sie benutzerdefinierte Element sm-cmd Browser verwenden, weiß nicht, welches Rendering-Modell zu verwenden (Block oder Inline). Standardmäßig wird inline eins angewendet, was zu einer Kollision in Bezug auf Elementdimensionen führt, da Sie inline sm-cmd auf Blockebene haben. Der Browser berechnet die Blockmaße nicht korrekt.

So ist die Lösung dieses einfache CSS-Regel:

sm-cmd {display: block;} 

Auch stellen Sie sicher, dass jQuery-Plugin in ngAfterViewInit Haken initialisieren:

@Directive({ 
    selector: "[sm-sortable]" 
}) 
export class SMSortable{ 

    constructor(private el: ElementRef) {} 

    ngAfterViewInit() { 
     jQuery(this.el.nativeElement).sortable({ 
      start: function(event, ui) { 
       console.log("Old position: " + ui.item.index()); 
      }, 
      stop: function(event, ui) { 
       console.log("New position: " + ui.item.index()); 
      } 
     }); 
    } 
} 

Demo:http://plnkr.co/edit/QEd9wozXSZlqT07qr51h?p=preview

+0

Danke, das funktioniert wie ein Zauber. – tyrion

Verwandte Themen