2015-12-21 2 views
7

から除去した後、私はオプションと選択がKnockout.jsを介して処理されている選択ボックスを持っています。私はマテリアライズCSSを使用してこれをスタイルする必要があります。再初期化Materialize.css選択ボックスKnockout.js options配列

これは、選択ボックスの初期表示には問題ありません。また、オプションが追加された後に(オプション) 'optionsAfterRender'バインディングを使用してKnockout.js 'options' observableArrayにオプションが追加されると、 、しかし働く)。

オプションを削除するとき、Knockout.jsは 'optionsAfterRender'と似たものを提供しないため、マテリアライズCSSマジックの再初期化をトリガーする明白な方法はありません。

質問:あなたが見ることができる非狂気のオプションはありますか?

コード:

<select data-bind=" 

     options: options, 
     optionsText: function(item) { return optionsText[item] }, 
     value: displayedValue, 

     optionsAfterRender: function (option, item) { 
     setTimeout(function() { 
      $(option.parentElement).material_select(); 
     }, 0); 
     } 
    "> 
</select> 

(そうでなければ選択されたオプションが採取されていないので、 'のsetTimeout' が必要である。)

答えて

8

custom binding handlerはKnockoutJSとmaterial_selectようなカスタムUIコンポーネントを統合するためのより適切です。ここでは、そのようなハンドラを構築するための一つの方法です:

ko.bindingHandlers["materializeSelect"] = { 
 
    after: ['options'], 
 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    // Initial initialization: 
 
    $(element).material_select(); 
 
    
 
    // Find the "options" sub-binding: 
 
    var boundValue = valueAccessor(); 
 
    
 
    // Register a callback for when "options" changes: 
 
    boundValue.options.subscribe(function() { 
 
     $(element).material_select(); 
 
    }); 
 
    }, 
 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
 
    
 
    } 
 
}; 
 

 
function RootViewModel() { 
 
    var self = this, i = 2; 
 
    self.options = ko.observableArray([{id: 1, txt: "Option A"}, {id: 2, txt: "Option two"}]); 
 
    self.selectedOption = ko.observable(null); 
 
    
 
    // For testing purposes: 
 
    self.addOption = function() { self.options.push({id: ++i, txt: "Dynamic option " + i}); }; 
 
} 
 

 
ko.applyBindings(new RootViewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/js/materialize.min.js"></script> 
 
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/css/materialize.min.css" rel="stylesheet"/> 
 

 
<select data-bind="materializeSelect: { options: options }, 
 
        options: options, 
 
        optionsText: 'txt', 
 
        value: selectedOption"> 
 
</select> 
 

 
<button data-bind="click: addOption">Add option dynamically</button>

正直に言うと、私はそれはそれは明らかに変化selectオプションは気づいていないことを問題/不作為またはおそらくMaterializeCSSでさえバグだと感じ。 Select2とChosenのようなIIRCライブラリdoこの機能があります。いずれの場合においても

、MaterializeCSS が正しく予告動的に追加されたオプションを希望の場合、私はまだstuggest 1だけはるかに簡単なカスタムバインドハンドラ、使用したい:イェルーンの答えは、素晴らしいと正しい

ko.bindingHandlers["materializeSelect"] = { 
    after: ['options'], 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
    $(element).material_select(); 
    }, 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
    // Handle ViewModel changes of which MaterializeCSS needs custom 
    // notification here. 
    } 
}; 
+0

私は通常 '.material_select(「破棄」)を呼び出す;'再初期化する前に念のために。materializecssはちょっと若いimho –

+0

私が持っていた次の問題を解決した、完璧な答えのおかげで、KOモデルの価値の変化の後に再初期化する方法! – gzost

0

を私が思うに、私はSOのコメントを使用して補遺を追加したいが、これは完全なフォーマットで見られる優れています。

Materializeは、selectに配置したときにdisableバインディングに応答すると少し変わっているようです。特に、そのdisableが別のノックアウトobservable(通常はこれです)の更新に依存している場合は特にそうです。

私は私の更新機能で次のコマンドを使用します。

if(allBindings().disable != undefined && allBindings().disable == true){ 
    $(element).prop("disabled", true); 
} 
else{ 
    $(element).prop("disabled", false);  
} 

$(element).material_select(); 

私が最初にちょうど更新機能で$(element).material_select()を呼び出して、それが少しwishy washyようだ、唯一の時間の一部を作業しようとしました。要素のdisabledプロパティを明示的に変更すると、毎回動作するようです。

は、おそらくこれを行うにははるかに簡潔な方法があるのですが、うまくいけば、この例では、ポイントを示しています。明示的結合の状態に基づいて、disabledプロパティを設定します。

他のバインディング、visibleなどを使用して同様の問題が発生しているかどうかわかりませんが、そうであれば同様の方法で解決できる可能性があります。