2017-01-22 7 views
5

Aureliaで動作するようにブートストラップマルチセレクトを取得しようとしています。それは多かれ少なかれ動作しているが、それが最良の解決策であるかどうか、または問題に遭遇する可能性があるかどうかはわからない。Aureliaのboostrap-multiselectプラグイン

ブートストラップ・複数選択チェックボックス(http://davidstutz.github.io/bootstrap-multiselect/)とドロップダウンに(マルチ)通常の選択をオンjQueryプラグイン

私の最初の問題は、それが動的に作成オプションを使用して作業を取得することです。私は、(バインド可能なプロパティとして作成された)配列の配列が変更されたときに、プラグインの "再構築"機能を使用して解決しました。しかし、元のselect hhasのオプションはまだ作成されていないので、setTimeoutを使用して再構築を遅らせることで、Aureliaはselectを再構築しました。 「汚れた」解決策のような気がして、私はAureliaのライフサイクルについてはそれがいつもうまくいくことを知っています。

第2の問題は、コンポーネントの値は更新されませんが、変更メソッドは起動されます。私は変更イベントを実行することでこれを解決しました(同じことをする他のプラグインの例が見つかりました)。うまく動作し、値は更新されますが、変更メソッドは2回発生します。大きな問題ではありませんが、データベースなどからデータを取得するなど、時間のかかる作業が必要な場合は問題になる可能性があります。

コードを改善するためのアドバイスはありますか?

 <template> 
      <select value.bind="value" multiple="multiple"> 
       <option repeat.for="option of options"Value.bind="option.value">${option.label}</option> 
      </select> 
     </template> 

import {customElement, bindable, inject} from 'aurelia-framework'; 
 
import 'jquery'; 
 
import 'bootstrap'; 
 
import 'davidstutz/bootstrap-multiselect'; 
 

 
@inject(Element) 
 
export class MultiSelect { 
 

 
    @bindable value: any; 
 
    @bindable options: {}; 
 
    @bindable config: {}; 
 

 
    constructor(private element) { 
 
     this.element = element; 
 
    } 
 

 
    optionsChanged(newVal: any, oldVal: any) { 
 
     setTimeout(this.rebuild, 0); 
 
    } 
 

 
    attached() { 
 
     var selElement = $(this.element).find('select'); 
 
     selElement.multiselect(
 
      { 
 
       includeSelectAllOption: true, 
 
       selectAllText: "(All)", 
 
       selectAllNumber: false, 
 
       numberDisplayed: 1, 
 
       buttonWidth: "100%" 
 

 
      }) 
 
      .on('change', (event) => { 
 
       if (event.originalEvent) { return; } 
 
       var notice = new Event('change', { bubbles: true }); 
 
       selElement[0].dispatchEvent(notice); 
 
      }); 
 
    } 
 

 
    detached() { 
 
     $(this.element).find('select').multiselect('destroy'); 
 
    } 
 
    
 
    rebuild =() => { 
 
     $(this.element).find('select').multiselect('rebuild'); 
 
    } 
 
}

+0

私はDataTableで同じ種類の問題を抱えていて、自分で作成しました。 Aureliaのバインディングは素晴らしいですが、私はまだDOMの更新が完了したときにイベントを発生させる方法を学んでいません。それでは、正しいタイミングでコンポーネントの 'rebuild'メソッドを実行する方法について注意を向けるべきです。 – LStarky

答えて

1

あなたの最初の問題は、optionsChanged()ハンドラ内で、microTaskQueueに$(this.element).find('select').multiselect('rebuild');を押すことによって解決することができます。このように、Aureliaは新しいオプションをレンダリングした後、このイベントを開始します。

2番目の問題は実際問題ではありません。何が起こっているのは、デフォルトでは@bindableのプロパティが一方向であるということです。 valueプロパティは双方向として宣言する必要があります。次に、multiselect.changeイベント内のvalueを更新する必要があります。例を実行する

import {inject, bindable, bindingMode, TaskQueue} from 'aurelia-framework'; 

@inject(TaskQueue) 
export class MultiselectCustomElement { 

    @bindable options; 
    @bindable({ defaultBindingMode: bindingMode.twoWay }) value = []; 

    constructor(taskQueue) { 
    this.taskQueue = taskQueue; 
    } 

    attached() { 
    $(this.select).multiselect({ 
     onChange: (option, checked) => { 
     if (checked) { 
      this.value.push(option[0].value); 
     } else { 
      let index = this.value.indexOf(option[0].value); 
      this.value.splice(index, 1); 
     } 
     } 
    }); 
    } 

    optionsChanged(newValue, oldValue) { 
    if (oldValue) { 
     this.taskQueue.queueTask(() => { 
     this.value = []; 
     $(this.select).multiselect('rebuild'); 
     }); 
    } 
    } 
} 

https://gist.run/?id=60d7435dc1aa66809e4dce68329f4dab

は、この情報がお役に立てば幸い

最後に、あなたのカスタム要素は次のようなものでなければなりません!

+0

ありがとうございます。今まであなたに返信してくれなかったことを申し訳ありません。あなたが私を助けることに困っている時、それは私にとって非常に失礼です。私は今までこれは仕事の種類だったので、これについて忘れていたプロジェクトの他の部分に取り組んでいた。私はbindignがデフォルトで2つの方法であると思った= selectのテンプレートのバインディングをvalue.two-wayに変更した。私はあなたのコードをきれいにしようとします。選択した値をコードで選択することはできませんが、その値を取得しようとします。 –

関連する問題