javascript - knockout "with"绑定(bind)、级联下拉、重新加载选定值不起作用

标签 javascript knockout.js drop-down-menu cascading

我有一个 knockout 示例,使用“With”绑定(bind)创建级联下拉菜单。

下拉菜单工作正常,如果我选择值,4 个下拉菜单与每个相应的选择选项级联。

但是我想保存下拉设置,所以在页面加载时,我可以取回保存的值,就​​像预设值一样。

从下拉列表中选择后,通过调用“保存”注销可观察对象获得的值。但是在调用“loadPresetData”模拟数据映射到可观察的选定值时不起作用。

我已经 fork 了下面的 fiddle 。 http://jsfiddle.net/turrytheman/3urLenmd/

var sampleModel=[{"products":[{"name":"1948 Porsche 356-A Roadster","year":[{"name":2015,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]}]},{"name":"1948 Porsche Type 356 Roadster","year":[{"name":2014,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]},{"name":2015,"months":[{"name":"oct"},{"name":"marc"},{"name":"feb"}]}]},{"name":"1949 Jaguar XK 120","year":[{"name":2019,"months":[{"name":"oct"},{"name":"jun"},{"name":"jul"}]},{"name":2013,"months":[{"name":"oct"},{"name":"marc"},{"name":"feb"}]}]}],"name":"Classic Cars"},{"products":[{"name":"1936 Harley Davidson El Knucklehead","year":[{"name":2011,"months":[{"name":"jan"},{"name":"nov"},{"name":"sep"}]}]},{"name":"1957 Vespa GS150","year":[{"name":2014,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]},{"name":2015,"months":[{"name":"another"},{"name":"yet"},{"name":"another"}]}]}],"name":"Motorcycles"}];


var Cascading = function() {
    var self = this;
    self.category = ko.observable();
    self.product = ko.observable();
    self.years = ko.observable();
    self.month = ko.observable();

    // Whenever the category changes, reset the product selection
    self.category.subscribe(function(val) {
       self.product(undefined);
    });
    self.product.subscribe(function(val) {
       self.years(undefined);
    });
    self.years.subscribe(function(val) {
       self.month(undefined);
    });

    // Operations
    self.loadPresetData = function() { //simulating a load, recieved from AJAX, setting saved values
        self.category(JSON.parse('{"products":[{"name":"1936 Harley Davidson El Knucklehead","year":[{"name":2011,"months":[{"name":"jan"},{"name":"nov"},{"name":"sep"}]}]},{"name":"1957 Vespa GS150","year":[{"name":2014,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]},{"name":2015,"months":[{"name":"another"},{"name":"yet"},{"name":"another"}]}]}],"name":"Motorcycles"}'));
        self.product(JSON.parse('{"name":"1936 Harley Davidson El Knucklehead","year":[{"name":2011,"months":[{"name":"jan"},{"name":"nov"},{"name":"sep"}]}]}'));
        self.years(JSON.parse('{"name":2015,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]}'));
        self.month(JSON.parse('{"name":"april"}'));
}
    self.save = function() {
        var data = {"category": ko.toJSON(ko.toJS(self.category)),
                    "product": ko.toJSON(ko.toJS(self.product)),
                    "years": ko.toJSON(ko.toJS(self.years)) ,
                    "month": ko.toJSON(ko.toJS(self.month)) 
                    }
        console.log(data);
    };
};

ko.applyBindings(new Cascading());

HTML:

<div class='liveExample'> 
   <div>
       <select data-bind='options: sampleModel, optionsText: "name", optionsCaption: "Select...", value: category'> </select>
   </div>
   <div data-bind="with: category">
       <select data-bind='options: products, optionsText: "name", optionsCaption: "Select...", value: $parent.product'> </select>
   </div>
      <div data-bind="with: product">
       <select data-bind='options: year, optionsText: "name", optionsCaption: "Select...", value: $parent.years'> </select>
   </div>
      <div data-bind="with: years">
       <select data-bind='options: months, optionsText: "name", optionsCaption: "Select...", value: $parent.month'> </select>
   </div>
   <button data-bind='click: loadPresetData'>Load</button>
   <button data-bind='click: save'>Save</button>

    <div style="color: red"data-bind="text:'Category :' + ko.toJSON(category)"></div>
    <div style="color: green"data-bind="text:'Product :' + ko.toJSON(product)"></div>
    <div style="color: blue"data-bind="text:'Year :' + ko.toJSON(years)"></div>
    <div style="color: black"data-bind="text:'Months :' + ko.toJSON(month)"></div>
</div>

最佳答案

简短回答:下拉列表未设置,因为您设置为 self.category()objectloadPresetData 中的其他下拉列表sampleModel 中不存在(或 fiddle 中的 sampleProductCategories)。

是的,有一个对象看起来JSON.parse() 创建的对象,并且具有相同的属性和嵌套数组,但它们完全不同的对象。他们会失败 Strict Equality Comparison or "=== comparison" .您可以通过设置 categorysampleProductCategories 数组本身的其他级联值来证明这个假设。

self.loadPresetData = function() {
   self.category(sampleProductCategories[1]);
   self.product(sampleProductCategories[1].products[0]);
   self.years(sampleProductCategories[1].products[0].year[0]);
   self.month(sampleProductCategories[1].products[0].year[0].months[0]);
};

现在,当 category 更新时,knockout 会在 sampleProductCategories 中查找此对象。它存在,因此 category 不会被设置为 undefined

这是一个 updated fiddle

关于javascript - knockout "with"绑定(bind)、级联下拉、重新加载选定值不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46707871/

相关文章:

javascript - 根据使用 Web 服务获取信息的另一个下拉框的选择填充第二个下拉框

CSS 下拉菜单在 IE9 中被容器截断

javascript - 将对象转换为对象数组

javascript - JavaScript 中符号 "+"的含义?

javascript - 如何将相关单元格悬停到 jQuery?

javascript - 如何将变量从子状态传递到父状态AngularJs ui-router

KnockoutJS foreach 中的 jQuery 单击绑定(bind)不起作用

html - 需要在html中发送 bool 值

javascript - 将不同的 json 数据映射到可观察数组

css - 更改聚焦选择框选项的背景颜色不起作用