2014-02-19 62 views
0

請參閱本jsfiddle與knockout.js和選擇2層疊下拉菜單

我遇到兩個問題:

  1. 我無法返回選定對象的(cascadingOption)文本。
  2. 我失去了如何忠實地將下拉菜單翻譯爲select2。

具體做法是:

<select id="make" data-bind="options: carMakers, 
           value: selectedMake, 
           optionsText : 'text', 
           optionsCaption : 'Select your make'"> 
    </select><br/> 
    Selected Make: <span data-bind="text: selectedMake"></span><br/> 

返回[對象的對象]到屏幕上。如果我將最後一行更改爲span data-bind="text: selectedMake.text",則它不返回任何內容。但是,如果我從knockout使用subscribe並登錄到控制檯,我可以返回object.text的罰款嗎?

第二個問題是當我通過將select2: { }添加到其數據綁定屬性來更改第一個選擇標記時。這將正確地將下拉菜單更改爲select2樣式,但是所有級聯屬性都會崩潰。

任何幫助或指導將不勝感激。

回答

2

selectedMake是可觀察的,其值將是cascadingOption實例。要在跨度使用:文字綁定,您將需要:

<span data-bind="text: selectedMake().text"></span> 

它的工作原理,當你使用訂閱,因爲你得到的觀察到的值。


Select2嘗試將select元素與其內部狀態進行同步。不幸的是,它依賴於每個具有Id值的選項。因爲你不使用optionsValue綁定,所以這是行不通的。我也使用select2,但我已經改變了他們的代碼,以使用optionIndex而不是Id和相當複雜的select2綁定來管理差異,如Ajax和多選。

但是,你得到你的樣品與選擇2的工作...

  1. 創建一個可觀察到存儲的ID。
  2. 更改您的值綁定使用Id observable
  3. 添加optionsValue綁定以從您的源選項返回唯一標識。這將用於同步select2選項和選擇選項。
  4. 訂閱添加到ID可觀察到過濾器的選項,並從你的選擇陣列
  5. 返回對象的訂閱添加到可觀察到保存ID同步的值(小心的2個訂閱之間無限循環)

我已更新您的JSFiddle,但差異如下。在此我創建一個包裝函數,以構建一個可觀察/ id對,訂閱間距爲2. 選擇綁定具有不同的值綁定值和添加的選項值綁定 跨度綁定具有不同的文本綁定值。

HTML

<div> 
    <select id="make" data-bind="options: carMakers, value: selectedMake.id, optionsValue: 'text', optionsText : 'text', optionsCaption : 'Select your make', select2: {}"></select><br/> 
    Selected Make: <span data-bind="text: selectedMake().text"></span><br/> 
    <select id="type" data-bind="options: carTypes, value: selectedType.id, optionsValue: 'text', optionsText : 'text', optionsCaption : 'Select your type', enable : carTypes, select2: {}"></select><br/> 
    Selected Model: <span data-bind="text: selectedType().text"></span><br/> 
    <select id="model" data-bind="options: carModels, value: selectedModel.id, optionsValue: 'text', optionsText : 'text', optionsCaption : 'Select your Model', enable: carModels, select2: {}"></select><br/> 
    Selected Model: <span data-bind="text: selectedModel().text"></span><br/> 
</div> 

的Javascript

var makeObservableForSelect2 = function(sourceOptions, idSelector) { 
    var target = ko.observable({}); 
    target.id = ko.observable(); 

    target.id.subscribe(function(id) { 
     var realSource = ko.unwrap(sourceOptions) 
     if (!realSource) { 
      return; 
     }; 
     // Don't set target if id already matches to stop infinite loop. 
     if (target() && target()[idSelector] === id) { 
      return; 
     } 

     target(realSource.filter(function(item) { return item[idSelector] === id; })[0] || {}); 
    }); 

    target.subscribe(function(value) { 
     // Don't set id if id already matches to stop infinite loop. 
     if (target.id() && value[idSelector] === target.id()) { 
      return; 
     } 

     target.id(value[idSelector]); 
    }); 

    return target; 
}; 

var viewModel = { 
    carMakers: buildData() 
}; 

viewModel.selectedMake = makeObservableForSelect2(viewModel.carMakers, 'text'); 

viewModel.carTypes = ko.computed(function(){ 
    return viewModel.selectedMake() ? viewModel.selectedMake().childOptions : null; 
}); 

viewModel.selectedType = makeObservableForSelect2(viewModel.carTypes, 'text'); 

viewModel.carModels = ko.computed(function(){ 
    return viewModel.selectedType() ? viewModel.selectedType().childOptions : null; 
}); 

viewModel.selectedModel = makeObservableForSelect2(viewModel.carModels, 'text'); 
2

工作小提琴:http://jsfiddle.net/jiggle/Lw2qJ/

問題1:

你可以做span data-bind="text: selectedMake().text"(注意方括號),但只有當selectedMake總是要有一個值(因此具有.text屬性)。

還有一些其他的方法可以做到這一點,這是在http://www.knockmeout.net/2011/08/simplifying-and-cleaning-up-views-in.html

問題概述2:

然而,當我開始尋找第2期,我發現optionsValue屬性必須被設置select2才能正常工作(雖然有人可以糾正我),所以我重構了一點點,所以你的selectedMake不再是對象,而是文本屬性和optionsValue:「text」like like:

<select id="make" data-bind="select2:{} , options: carMakers, value: selectedMake, 
optionsValue:'text', 
optionsText : 'text', optionsCaption : 'Select your make'"></select><br/> 

這意味着你的級聯computeds下一個水平,你必須改變它首先從這樣的化妝所選文本值查找廠名:

viewModel.carTypes = ko.computed(function(){ 
if(viewModel.selectedMake()){ 
    var make = ko.utils.arrayFirst(viewModel.carMakers,function(item){ 
     console.log(item.text,viewModel.selectedMake()); 
      return item.text===viewModel.selectedMake();   
    }); 
    return make.childOptions; 
} 
}); 

這也意味着,你可以只使用Selected Make: <span data-bind="text: selectedMake"></span>而比使用方括號,因爲你不想訪問observable的屬性。

這裏的小提琴再次:http://jsfiddle.net/jiggle/Lw2qJ/

希望它能幫助。