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/