2013-10-31 25 views
2

這不工作(自定義綁定的調用,但下拉列表是空的)Knockout - 是否可以將標準選擇綁定與自定義綁定結合起來?

<select id="parentArea" class="chosen-select" data-bind=" 
    chosen:{}, 
    options: parentAreas, 
    optionsCaption: 'Choose...', 
    optionsText: 'Label', 
    value: selectedParentArea"> 
</select> 

但這個工程(下拉列表填充)

<select id="parentArea" class="chosen-select" data-bind=" 
    options: parentAreas, 
    optionsCaption: 'Choose...', 
    optionsText: 'Label', 
    value: selectedParentArea"> 
</select> 

我想添加自定義綁定到下拉列表,但不知道該怎麼做。

定製結合是簡單

ko.bindingHandlers.chosen = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     console.log('chosen', element); 
     $(element).chosen({}); 
    } 
}; 

UPDATE

.chosen({});

是另一塊Javascript的方法(harvesthq.github.io/chosen)。

我意識到當它被註釋掉時,剩下的綁定工作。 我真正需要的是運行「$(element).chosen({});」完成所有其他約束後。

UPDATE 2

當我申請「選擇」應用了所有綁定後手動,它工作得很好。例如,我可以用它運行這個JS

function run() { 
    $('.chosen-select').chosen({}); 
};  

我只需要自動做一個按鈕(一個回調函數?)當所有綁定完成。 我不知道該怎麼做。

UPDATE 3

「parentAreas」不是靜態數組。它從網絡服務加載:

function ViewModel() { 

    var self = this; 

    self.init = function() { 

     //load parent areas from web service 
    }; 

    self.init(); //Running the init code 
} 

ko.applyBindings(new ViewModel()); 

我想初始化「選擇」框自定義綁定時父區域準備就緒。

UPDATE 4

新版本(的作品,但不可重複使用的,因爲它已經硬編碼綁定)

ko.bindingHandlers。選擇= { INIT:功能(元件,valueAccessor,allBindingsAccessor,視圖模型,上下文){

 viewModel.parentAreas.subscribe(function(newParentAreas) { 
      if (newParentAreas && newParentAreas.length > 0) { 

       ko.applyBindingsToNode(element, { 
        options: viewModel.parentAreas, 
        optionsCaption: 'Choose...', 
        optionsText: 'Label', 
        value: viewModel.selectedParentArea 
       }); 
       $(element).chosen({}); 
      } 
     }); 
    } 
}; 

//和結合僅僅是數據綁定=「選自:{}

UPDATE 5 避免多個初始化(哈克的方式)

ko.bindingHandlers.parentAreaComboBox = { 

    initialised: false, 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) { 

     viewModel.parentAreas.subscribe(function (newParentAreas) { 

      if (newParentAreas && newParentAreas.length > 0) { 

       if (ko.bindingHandlers.parentAreaComboBox.initialised) { 
        return; 
       } 
       ko.applyBindingsToNode(element, { 
        options: viewModel.parentAreas, 
        optionsCaption: 'Choose...', 
        optionsText: 'Label', 
        value: viewModel.selectedParentArea 
       }); 
       $(element).chosen({}); 
       ko.bindingHandlers.parentAreaComboBox.initialised = true; 
      } 
     }); 
    } 
}; 

UPDATE 6

我已經寫了通用的解決方案(見我的回答如下)

+0

是什麼$(元素)。 **選擇**({}); –

+1

好問題。 「.chosen({});」是另一塊Javascript的一種方法(http://harvesthq.github.io/chosen/)。我意識到當它被註釋掉時,剩下的約束性工作。我需要的是運行「$(element)。selected({});」完成所有其他約束後。 –

+0

雖然 – Anders

回答

3

它,你依賴綁定的數量級上的反模式。

如果你有一個自定義綁定,需要其他綁定itsself運行之前,你應該叫那些綁定從自定義喜歡

ko.applyBindingsToNode(element, { options: arr, value: val }); 

結合,之後做$(element).chosen

+0

謝謝!它適用於「arr」是靜態數組的情況。但它是從Web服務加載的(請參閱更新3)。所以當'選擇'自定義綁定被初始化時它是空的。 –

+0

你需要使用一個observableArray然後 – Anders

+0

parentAreas是一個observableArray; self.parentAreas = ko.observableArray([]); –

1

是啊,只是重新排序綁定(提琴:http://jsfiddle.net/gBhbx/4/):

<select id="parentArea" class="chosen-select" data-bind=" 
    options: parentAreas, 
    optionsCaption: 'Choose...', 
    optionsText: 'Label', 
    chosen:{}, 
    value: selectedParentArea"> 
</select> 
+0

不適用於我。 –

+0

嗯,它是無風格的(沒有加載選擇的CSS),但它應該工作。如果你點擊第一個文本框並點擊一個選項,它將被選中。更新小提琴:http://jsfiddle.net/gBhbx/5/,檢查控制檯 – pax162

+0

是的,版本5(jsfiddle.net/gBhbx/5)在jsFiddle中工作。我已經刪除(非常混亂)'chosenSimple'選擇和示例仍然有效http://jsfiddle.net/LzjLH/ –

1

我覺得你的問題是在chosen插件本身。當您在select標籤上應用.chosen時,它會更改其標記(它不再是普通的html select)。
所以在你bindning您的申請chosen自定義綁定第一,然後改變HTML標記,因此你的綁定工作不正常..

爲了解決您需要申請您的自定義不是第一次結合最後這個問題。 。使KO結合通常會應用應用您的自定義綁定和option後改變你的選擇(不過現在您已經構建了選擇正確)

更新

運行功能元素產生可以使用optionsAfterRender回調。檢查出來的文件建立here

另一個解決方案是使用settimeout

+0

謝謝!這是我在「更新」部分寫的:「我真正需要的是運行」$(element).chosen({});「在所有其他綁定完成後。」但我不知道該怎麼做。 –

+0

@MaximEliseev請點擊這裏查看文檔:http://knockoutjs.com/documentation/options-binding.html#note_2_postprocessing_the_generated_options –

+0

請注意,optionsAfterRender爲選擇列表中的每個項目運行。我可以編程,所以它只能運行第一項。我會是一個有點冒險的解決方案。我可以嘗試。 –

1

的通用解決方案

HTML

<select id="parentArea" data-bind="comboBox:{ options: parentAreas, optionsCaption:'Choose...' , optionsText: 'Label', value: selectedParentArea }"></select>

和JavaScript是

ko.bindingHandlers.comboBox = { 

    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) { 
     var bindings = valueAccessor(); 
     var optionsObservableArray = bindings.options; 
     optionsObservableArray.subscribe(function (newObservableArray) { 

      if (newObservableArray && newObservableArray.length > 0) { 

       if (element.comboBoxInitialised) { 
        return; 
       } 

       ko.applyBindingsToNode(element, { 
        options: bindings.options, 
        optionsCaption: bindings.optionsCaption, 
        optionsText: bindings.optionsText, 
        value: bindings.value 
       }); 
       $(element).chosen({}); 
       element.comboBoxInitialised = true; 
      } 
     }); 
    } 
}; 
相關問題