无法获得 optionsValue 以使用依赖下拉菜单和 Knockout 映射插件

Unable to get optionsValue to work with dependent dropdowns and the Knockout mapping plugin

我是一名数据库开发人员(存在 问题)负责发出 JSON 以与 Knockout.js 一起使用以呈现依赖列表项集。我刚刚开始使用 Knockout,所以这很可能是我遗漏的东西。

这是标记:

<select data-bind="options:data,
                   optionsText:'leadTime',
                   value:leadTimes">
</select>

<!--ko with: leadTimes -->
    <select data-bind="options:colors,
                       optionsText:'name',
                       optionsValue:'key',
                       value:$root.colorsByLeadTime">
    </select>
<!--/ko-->

这里是测试数据和代码:

var data = [
    {
        key:"1",
        leadTime:"Standard",
        colors:[
            { key:"11", name:"Red" },
            { key:"12", name:"Orange" },
            { key:"13", name:"Yellow" }
        ]
    },
    {
        key:"2",
        leadTime:"Quick",
        colors:[
            { key:"21", name:"Black" },
            { key:"22", name:"White" }
        ]
    }
]

var dataViewModel = ko.mapping.fromJS(data);

var mainViewModel = {
    data:dataViewModel,
    leadTimes:ko.observable(),
    colorsByLeadTime:ko.observable()
}

ko.applyBindings(mainViewModel); 

就目前而言,它正确地填充了第二个 select 列表的 value 属性。但是,如果我将 optionsValue:'key' 添加到第一个 select 列表,那么它的 value 属性设置正确,但第二个 select 列表呈现为空列表。

我只需要将 option 标记的 value 属性设置为数据中提供的 key 值,而不管 select 在哪里列表在依赖列表的集合中。我看过很多文章和文档,但我无法理解这种特殊情况(我认为这很常见)。

这是一个带有上面给出的数据、JS 和标记的 jsfiddle:http://jsfiddle.net/tnagle/Lyxjt11y/

要真正看到问题,可以在mainViewModel初始化后添加如下代码。

mainViewModel.leadTimes.subscribe(function(newValue) { 
  console.log(newValue);
  debugger; 
});

在添加 optionsValue:'key' 之前,上面的行将记录以下输出。

Object {key: function, leadTime: function, colors: function}

但是在添加 optionsValue:'key' 之后,它会记录以下输出。

"1"

"2"

失败的原因是当您将 optionsValue: 'key' 分配给第一个 select 列表时,您的 mainViewModel 的 leadTimes 属性 之前将包含一个对象属性 颜色,现在将设置为字符串对象。然后 select 列表未能从 leadTimes 中找到已更改为字符串对象的 color 属性。

使其工作的一种方法是更改​​为:

var data = [
  {
    key:"1",
    leadTime:"Standard",
    colors:[
      { key:"11", name:"Red" },
      { key:"12", name:"Orange" },
      { key:"13", name:"Yellow" }
    ]
  },
  {
    key:"2",
    leadTime:"Quick",
    colors:[
      { key:"21", name:"Black" },
      { key:"22", name:"White" }
    ]
  }
]

var dataViewModel = ko.mapping.fromJS(data);

var mainViewModel = new function (){
  var self = this;
  self.data = dataViewModel;
  self.leadTimes = ko.observable();
  self.selectedKey = ko.observable();
  self.selectedKey.subscribe(function(selectedKey){
 self.selectedData(ko.utils.arrayFirst(self.data(), function(item) {
        return item.key() == selectedKey;
    }));
  }, self); 
  self.colorsByLeadTime = ko.observable();
  self.selectedData = ko.observable();
}

ko.applyBindings(mainViewModel);
<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/knockout.mapping/2.3.5/knockout.mapping.js"></script>    

<select data-bind="options:data,
               optionsText:'leadTime',
               optionsValue:'key',
               value:selectedKey">
</select>   
  
<!--ko with: selectedData -->
<select data-bind="options:colors,
                   optionsText:'name',
                   optionsValue:'key',
                   value:$root.colorsByLeadTime">
</select>
<!--/ko-->