隐藏无线电选项取决于淘汰赛中的其他单独无线电选项

时间:2013-07-14 22:12:00

标签: json knockout.js

我打算在我的表格上有两套电台选项,一部电台叫Operating System,另一部电台叫Database

Operating System无线电选择的选项指示Database无线电组中可供选择的值。

在我的json对象中,requires字段表示选择操作系统的sku时选项的可见性。如果没有为数据库选项提供requires字段,则无论选择何种操作系统,它都将始终可用。

如何在淘汰赛中接近这一点,或者我是否需要重新考虑我的方法?

My jsfiddle is here

var osOptions = [{
  name: "Windows Standard",
    sku: "201",
},{
    name: "Windows Enterprise",
    sku: "202",
}, {
    name: "CentOS Linux",
    sku: "203",
}, {
    name: "Debian",
    sku: "204",
}];

var databaseOptions = [{
    name: None,
}, {
    name: "SQL Express",
    sku: 401,
    requires: ["201", "202"]
}, {
    name: "SQL Standard",
    sku: 402,
    requires: ["202"]
}, {
    name: "MySQL",
    sku: "MySQL1",
    requires: ["201", "202", "203"]
}, {
    name: "RavenDb",
    sku: 403,
}, {
    name: "MongoDB",
    sku: 404,
    requires: ["204"]
}];

function viewModel() {
    this.os = osOptions;
    this.database = databaseOptions;
    this.selectedOs = ko.observable();
    this.selectedDb = ko.observable();
}
ko.applyBindings(new viewModel);

<!- view html -->
<h1>Select OS:</h1>
<div data-bind="foreach: os" >
    <div>
        <input type="radio" name="optionsGroup" data-bind="attr: {value: name}, checked: $root.selectedOs" />
        <span data-bind="text: name"></span>
    </div>    
</div>
<h1>Select Db</h1>
<div data-bind="foreach: database" >
    <div>
        <input type="radio" name="optionsGroup" data-bind="attr: {value: name}, checked: $root.selectedDb" />
        <span data-bind="text: name"></span>
    </div>    
</div>

2 个答案:

答案 0 :(得分:3)

我会创建一个不同的计算集合availableDatabases其中

  • 首先我会查找当前选择的操作系统
  • 然后我会使用ko.utils.arrayFilter过滤掉requires数组中不包含所选sku的数据库。

所以我会这样写:

this.availableDatabases = ko.computed(function() {
    var selectedOsName = this.selectedOs();

    var selectedOs = ko.utils.arrayFirst(this.os, function(os){
       return os.name ==  selectedOsName;
    }, this);

    if (!selectedOs)
        return [];

    return ko.utils.arrayFilter(this.database, function(db){
        return db.requires && db.requires.indexOf(selectedOs.sku) > -1;
    }, this)

}, this);

在视图中使用此新集合:

<div data-bind="foreach: availableDatabases" >
    <div>
        <input type="radio" name="optionsGroup" 
             data-bind="attr: {value: name}, checked: $root.selectedDb" />
        <span data-bind="text: name"></span>
    </div>    
</div>

演示JSFiddle.

注意如果您有第一个单选按钮sku而不是name作为value

<input type="radio" name="optionsGroup" 
                    data-bind="attr: {value: sku}, checked: $root.selectedOs" />

然后计算中不需要查找,因为selectedOs将直接包含sku属性(Demo)...

答案 1 :(得分:2)

查看this fiddle

您可以创建一个用于检索可用数据库的计算器。

JS:

function viewModel() {
    var self = this;
    this.os = osOptions;
    this.database = databaseOptions;
    this.selectedOs = ko.observable();
    this.selectedDb = ko.observable();

    this.availableDatabase = ko.computed(function () {
        var osSku = self.selectedOs();
        return ko.utils.arrayFilter(self.database, function (dbItem) {
            if (osSku == null) return false;

            if (dbItem.requires == null) return true;

            var dbs =  ko.utils.arrayFirst(dbItem.requires, function (requiredOS) {
                return requiredOS == osSku;
            }) != null;
            return dbs;

        });

    });
};
ko.applyBindings(new viewModel);

我希望它有所帮助。