2016-03-23 6 views
4

私の目的は、ユーザーがコマンドのリストをソートできるようにすることです。 Angular2/Typescriptを使ってアプリケーションを開発しています。JQueryUI Angular2でカスタムコンポーネントを使用しているときにSortableが動作しない

私はJQueryUI Sortableに似たソート可能な機能を提供するかもしれないangular2ベースのライブラリについて調べましたが、それほど多くは見つかりませんでした。

私はthis SO postに出くわしました.JQueryをangular2と統合する方法を示しました。このポストの解決策の1つで提供されたplunkを使って、私はangular2でソート可能な動作を開発することができました。これはplunkを参照してください。これは期待どおりに動作しています。

@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' 
    } 
} 

アイデアはJQueryUIソート可能()APIを使用してネイティブの要素にソート可能な振る舞いを適用するディレクティブを定義することでした。次に、コンポーネントのテンプレートでディレクティブを使用します。

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

これは、コンポーネントのテンプレートにすべてのネイティブエレメントがある場合にうまく機能します。しかし、テンプレートにカスタムangle2コンポーネントがある場合、これは機能しなくなります。

この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 { 

} 

この場合、アイテムをドラッグできますが、ドロップできません。移動した項目は元の位置に戻ります。私はconsole.logを追加して、ソート中にイベントの開始時と終了時に項目インデックスを表示しました。値は変わりません。

これ以上デバッグできません。誰かがこれに関するいくつかの情報を提供できますか?

+0

ポスト非稼働plunkr。 – dfsq

+0

実際に働いていないプランカーは間違っていますか? –

+0

はい、実際に動作していません。 – micronyks

答えて

5

問題は実際には非常に簡単です:カスタム要素sm-cmdを使用しているため、ブラウザはどのレンダリングモデルを使用するのか(ブロックまたはインライン)はわかりません。デフォルトでは、ブロックレベルがpのインラインsm-cmdになっているため、インライン1が適用され、要素の次元での衝突が発生します。したがって、ブラウザはブロックの寸法を正しく計算しません。

だから、解決策は、この単純なCSSルールです:

sm-cmd {display: block;} 

また、あなたがngAfterViewInitフックでjQueryプラグインを初期化していることを確認します

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

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

+0

ありがとう、これは魅力のように動作します。 – tyrion

関連する問題