我有一个产品选项列表,每个选项都有一个从服务器作为 JSON 接收的 sku 标识符。然后我有其他选项取决于选择的先决条件值,这是由requires
产品选项数组的数组属性定义的:
var serverOptions = [{
name: "DELL R210",
price: 100,
sku: 1001,
},{
name: "DELL R710",
price: 200,
sku: 1002,
},{
name: "DELL R720 Dual CPU",
price: 300,
sku: 1003,
}];
var osOptions = [{
name: "Windows Standard",
sku: "201",
price: 1,
}, {
name: "Windows Enterprise",
sku: "202",
price: 2,
}, {
name: "CentOS",
sku: "203",
price: 0,
}, {
name: "Debian",
sku: "204",
price: 4,
}];
var databaseOptions = [{
name: "None",
sku: "0",
price: 0,
}, {
name: "SQL Express",
sku: "401",
requires: ["201", "202"],
price: 10,
}, {
name: "SQL Standard",
sku: "402",
requires: ["202"],
price: 5,
}, {
name: "MySQL",
sku: "MySQL1",
requires: ["201", "202", "203"],
price: 11,
}, {
name: "RavenDb",
sku: "403",
requires: ["203"],
price: 12,
}, {
name: "MongoDB",
sku: "404",
requires: ["204"],
price: 13,
}];
var clusterOptions = [{
name: "None",
sku: "0",
price: 0,
}, {
name: "Standard MySQL Cluster",
sku: "4101",
requires: ["MySQL1"],
price: 10,
}, {
name: "Enterprise MS SQL Cluster",
sku: "4102",
requires: ["402"],
price: 5,
}, {
name: "NoSQL Sharding",
sku: "4103",
requires: ["403","404"],
price: 10,
}];
然后,在我的视图模型中,我使用以下代码过滤可供选择的值(大多数情况下是通用的,变量引用会根据用于查询需要检查的内容而变化):
self.availableClusteringOptions = ko.computed(function () {
var selectedDbSku = this.selectedDb();
if (typeof selectedDbSku === "undefined")
return [];
return ko.utils.arrayFilter(this.dbClusteringOptions, function (dbCluster) {
if (typeof dbCluster.requires === "undefined")
return true;
else
return dbCluster.requires && dbCluster.requires.indexOf(selectedDbSku) > -1;
}, this);
}, this);
虽然我的代码有效,但它是由我手动预先静态输入的,当我添加新字段时,我正在做很多复制粘贴,因为代码语法相同,只是变量发生了变化(例如self.availableDatabases
和self.availableClusteringOptions
)。
将来我们可能会(从服务器数据库)添加一个全新的选项对象,这将需要动态处理、映射和创建关系。例如,可以添加的未来产品选项可能是:
var managementOptions = [{
name: "Self managed",
sku: "0",
price: "0"
},{
name: "Windows Management",
sku: "WindowsManagement",
price: 1,
requires: ["201", "202"],
}, {
name: "Linux Management",
sku: "LinxManagement",
requires: ["203", "204"],
price: 2,
}, {
name: "Basic Management",
sku: "ManageAll",
price: 0,
requires: ["201", "202","203","204"],
}];
这迫切需要自动化,特别是因为这些数据将来自数据库,但我不知道从哪里开始。
我已经看到了可以从 json 创建视图模型的淘汰映射插件,但是从文档中我不确定这将如何与我的数据结构联系起来,因为我的 JSON 比示例复杂得多。
如何自动化此代码以允许动态设置其他依赖的“需要”先决条件值?在这种情况下淘汰制图可以提供帮助还是我需要寻找其他途径?
小提琴在这里:http: //jsfiddle.net/g18c/E54YC/7/
var serverConfig = function () {
var self = this;
self.osOptions = osOptions;
self.dbOptions = databaseOptions;
self.dbClusteringOptions = clusterOptions;
self.serverOptions = serverOptions;
self.selectedServer = ko.observable();
self.selectedOs = ko.observable();
self.selectedDb = ko.observable();
self.selectedDbCluster = ko.observable();
self.lookupItemForSku = function (lookup, values) {
if ((typeof lookup != "undefined") && (lookup != "0"))
return ko.utils.arrayFirst(values, function (item) { return item.sku == lookup; }, this);
else
return null;
};
self.availableDatabases = ko.computed(function () {
var selectedOsSku = this.selectedOs();
if (typeof selectedOsSku === "undefined")
return [];
return ko.utils.arrayFilter(this.dbOptions, function (db) {
if (typeof db.requires === "undefined")
return true;
else
return db.requires && db.requires.indexOf(selectedOsSku) > -1;
}, this);
}, this);
self.availableClusteringOptions = ko.computed(function () {
var selectedDbSku = this.selectedDb();
if (typeof selectedDbSku === "undefined")
return [];
return ko.utils.arrayFilter(this.dbClusteringOptions, function (dbCluster) {
if (typeof dbCluster.requires === "undefined")
return true;
else
return dbCluster.requires && dbCluster.requires.indexOf(selectedDbSku) > -1;
}, this);
}, this);
self.availableDatabases.subscribe(function () {
self.selectedDb(self.availableDatabases()[0].sku);
});
self.availableClusteringOptions.subscribe(function () {
self.selectedDbCluster(self.availableClusteringOptions()[0].sku);
});
self.selectedServer(self.serverOptions[0].sku);
self.selectedOs(self.osOptions[0].sku);
return self;
};
var configModel = new serverConfig();
ko.applyBindings(configModel);