如何通常将依赖下拉菜单与淘汰赛挂钩

How to generically hook up dependent drop-downs with knockout

我有一个 json 结构,如下所示:

var scenario = {
    paints: [
       {
            product: 'Super Paint',
            sheens: [
                { sheen: 'Satin', cost: 42 },
                { sheen: 'Semi-Gloss', cost: 50 }
            ]
        },
        {
            product: 'Cashmere',
            sheens: [
                { sheen: 'Flat', cost: 42 },
                { sheen: 'Medium Lustre', cost: 50 }
            ]
        }
    ],
    walls: {
      "sheen":"Flat",
      "paintProduct":"Cashmere",
    },
    ceiling: {
      "sheen":"Flat",
      "paintProduct":"Cashmere",
   }
};

我现在想出使下拉菜单依赖于给定的可绘制项目,具有以下内容:

function getSheens(paintProduct) {
    if (paintProduct) {
        for (var i = 0; i < self.scenario.paints.length; ++i) {
            if (self.scenario.paints[i].product === paintProduct) {
                return self.scenario.paints[i].sheens;
            }
        }
    }
    return null;
}

self.scenario.walls.sheens = ko.computed(function() {
    return getSheens(self.scenario.walls.paintProduct());
});

self.scenario.ceiling.sheens = ko.computed(function() {
    return getSheens(self.scenario.ceiling.paintProduct());
});

这是html:

<div class="item edit-walls" data-bind="with: scenario.walls">
    <label>Product</label>
    <select class="form-control paint-product" data-bind="options:$parent.scenario.paints, optionsText:'product', optionsValue:'product', value:paintProduct"></select>

    <label>Sheen</label>
    <select class="form-control paint-sheen" data-bind="options:$parent.scenario.walls.sheens, optionsText:'sheen', optionsValue:'sheen', value:sheen"></select>
</div>

改变给定物品的油漆产品,应该重新加载新 select 油漆产品的光泽。

油漆产品的 selected 值和项目(即墙壁)的光泽存储在墙壁对象中。

我想避免的是为每种不同的项目类型重复计算出的敲除调用。有没有办法在全球范围内发生这种情况并以某种方式传递上下文?

我正在使用 knockout.js、knockout.viewmodel.js 和 jQuery。

你基本上是在问是否有可能将 "walls" 和 "ceiling" 规范化为一个概念。你当然可以。我们称它们为 paintables。将您的数据结构更改为如下所示:

var scenario = {
    paints: [/* omitted */],
    paintables: [
        { 
          "name":"walls",
          "sheen":"Flat",
          "paintProduct":"Cashmere"
        },
        { 
          "name":"ceiling",
          "sheen":"Flat",
          "paintProduct":"Cashmere"
    }]
};

然后你可以有一个 Paintable 构造函数,它以 DRY 方式实现你对 sheen 的逻辑。