1

我已經開始使用knockoutjs並做一些簡單的綁定/依賴綁定。 我的目標是根據另一個<select>列表的值來填充1 <select>列表。兩者都從ajax調用加載到我的asp.net web服務。Knockout JS中的依賴可觀測陣列

所以我有兩個<select>名單

<select id="make" data-bind="options: availableMakes, value: selectedMake, optionsText: 'text', optionsCaption: 'Choose a make'"></select> 
<select id="model" data-bind="options: availableModels, value: selectedModel, optionsText: 'text', optionsCaption: 'Choose a model'"></select> 

然後我的JavaScript看起來像這樣:

$(function() { 

      // creating the model 
      var option = function (text, value) { 
       this.text = text; 
       this.value = value; 
      } 

      // creating the view model 
      var searchModel = { 
       availableMakes: ko.observableArray([]), 
       availableModels: ko.observableArray([]), 
       selectedMake: ko.observable(), 
       selectedModel: ko.observable() 
      } 

      // adding in a dependentObservable to update the Models based on the selected Make 
      searchModel.UpdateModels = ko.dependentObservable(function() { 
       var theMake = searchModel.selectedMake() ? searchModel.selectedMake().text : ''; 
       if (theMake != '') { 
        $.ajax({ 
         url: "/data/service/auction.asmx/GetModels", 
         type: 'GET', 
         contentType: "application/json; charset=utf-8", 
         data: '{make:"' + theMake + '"}', 
         success: function (data) { 
          var makes = (typeof data.d) == 'string' ? eval('(' + data.d + ')') : data.d; 
          var mappedModels = $.map(makes, function (item) { 
           return new option(item.text, item.value); 
          }); 
          searchModel.availableModels(mappedModels); 
         }, 
         dataType: "json" 
        }); 
       } 
       else { 
        searchModel.availableModels([]); 
       } 
       return null; 
      }, searchModel); 

      // binding the view model 
      ko.applyBindings(searchModel); 

      // loading in all the makes 
      $.ajax({ 
       url: "/data/service/auction.asmx/GetMakes", 
       type: 'GET', 
       contentType: "application/json; charset=utf-8", 
       data: '', 
       success: function (data) { 
        var makes = (typeof data.d) == 'string' ? eval('(' + data.d + ')') : data.d; 
        var mappedMakes = $.map(makes, function (item) { 
         return new option(item.text, item.value); 
        }); 
        searchModel.availableMakes(mappedMakes); 
       }, 
       dataType: "json" 
      }); 

     }); 

目前這種按預期工作,但我認爲我做的這個錯誤的代碼如下相當長,我可以做到這一點,而不用少量代碼使用knockoutjs。 也是我加載了availableModels的方式顯然是不正確的,因爲我用的是dependentObsevable稱爲UpdateModels我爲了加載了availableModels增加的基礎上selectedMake().text

我希望值,這是有道理的,你可以指出一個改進版本嗎?或者簡單地告訴我如何根據Make選項重新加載模型?

非常感謝,

回答

4

我認爲你的代碼看起來非常正常。對於UpdateModels dependentObservable,實際上你可以使用手動訂閱selectedMake像:

searchModel.selectedMake.subscribe(function (newMake) { 
    if (newMake) { 
     //ajax request 
    } 
    else { 
     searchModel.availableModels([]); 
    } 
}, searchModel); 

這不會改變的功能,只是一個更明確的方式來訂閱一個可觀察的變化。

您也可以選擇在綁定中使用optionsValue: 'text'(或「值」),並且您的selectedMake將直接設置爲文本或值。如果您的模型是製作對象的子項,那麼您甚至可以將模型綁定到selectedMake().models(需要防止selectedMake爲null,這可以使用DO完成,1.3控制流綁定或內聯類似selectedMake() ? selectedMake().models : []

+0

謝謝。訂閱選項是我認爲我真的在尋找的選項。這使我可以跟蹤選定品牌的變化,然後加載模型。我嘗試添加'optionsValue'屬性,但這似乎導致我的'selectedMake'始終處於「未定義」狀態。我喜歡你的模型作爲製作的孩子的想法,所以也許可能會更新我的代碼。 –

2

我同意瑞安的答案。

服用了一下相關的切線,我重構有點不使用Ajax和簡化的例子(你可以隨時添加回)。但在這裏是一個小提琴,演示你正在尋找一些樣品數據。

http://jsfiddle.net/johnpapa/vGg2h/