Knockout.js 自动映射敲除中的依赖属性

Knockout.js 自动映射敲除中的依赖属性,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,我有一个产品选项列表,每个选项都有一个sku标识符,作为JSON从服务器接收。然后,我有其他选项,这些选项取决于所选择的先决条件值,这是由产品选项数组的requires数组属性定义的: var serverOptions = [{ name: "DELL R210", price: 100, sku: 1001, },{ name: "DELL R710", price: 200, sku: 1002, },{ name: "DELL R7

我有一个产品选项列表,每个选项都有一个sku标识符,作为JSON从服务器接收。然后,我有其他选项,这些选项取决于所选择的先决条件值,这是由产品选项数组的
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,
}];
然后,在我的viewmodel中,我使用以下代码过滤可供选择的值(大多数情况下是通用的,变量引用根据用于查询所需检查的内容而变化):

当我的代码工作时,它是由我手动预先静态键入的,当我添加新字段时,我会进行大量的复制粘贴,因为代码语法相同,只是变量发生了变化(例如
self.availabledabases
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创建viewmodel的knockout mapping插件,但是从文档中我不确定这将如何与我的数据结构相结合,因为我的json比示例要复杂得多

我如何能够自动执行此代码以允许动态设置其他依赖的“requires”先决条件值?在这种情况下,敲除映射是否有帮助,或者我是否需要寻找其他途径

小提琴在这里:


下面是对您的小提琴的快速更新,展示了如何创建自己的模型来映射数据-

如果你想变得更激烈,有关系映射,你有很多选择,但前两个我会考虑——

  • 编写自己的自定义代码来处理需求,并根据需求选择此代码还是那个代码

  • 使用客户端数据库(ORM)来处理它,就像Breeze.js一样,在那里关系映射是为您处理的,您只需要将逻辑放入视图模型中

  • 模型示例-

    function serverModel (server) {
        var self = this;
        self.Name = ko.observable(server.name);
        self.Price = ko.observable(server.price);
        self.SKU = ko.observable(server.sku);
    }
    

    更具体一点-你的意思是什么?你如何映射它?您是否有一个正在访问并从中获取一些数据的服务器端点?我需要尽可能地自动化此代码,其中有大量重复。从文档中,我相信映射将从json创建viewmodel,但我的案例比任何示例都要复杂,因此我不确定这是否可能,或者我是否应该寻找一个听起来不像驴子的替代方案,但与使用它的人数相比,您使用的模型非常轻量级。您可以使用映射插件,也可以在客户端上创建自己的模型以供重用。主要目的是使其动态化,因为数据将来自数据库。我的问题是如何映射
    requires
    功能,因为添加了其他字段,这将根据从服务器以JSON形式发送的内容动态出现。我已经读过关于ko映射的文章,但是我不确定如何开始我的代码,我非常希望能有一些指导。谢谢@PW Kad,所以如果我理解正确,更好的方法可能是编写我们自己的绑定机制?不确定它是否清晰,但实际的产品选项类型将是动态的(不仅仅是内容),我的意思是可能会发送一个全新的产品选项数组,即managemenOption[]。我将更新我的问题以避免混淆。感谢Breeze上的提示,我是javascript新手,这样的学习很有用,我已经尽可能地回答了您关于映射的问题,如果你有一个与技术有关的架构问题,你可以使用或构造你尝试过的方法,而不能找到一个解决方案来考虑将其标记为解决方案,并创建一个新的问题来详细描述你的问题。继续将问题链接到完全不相关的问题上是没有用的。我的问题从一开始就是,而且一直都是,关于根据筛选的可用选项动态自动映射属性。您的回答很有用,非常感谢,但并不能解决我的问题。映射插件就是这样做的,它动态映射所有内容。不知道你需要的答案有多好:)好吧,我承认:)在仔细考虑之后,我的问题得到了回答,我需要使用地图绘制工具。我已经尝试过ko.mapper,并在这里发布了关于这方面的具体问题
    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);
    
    function serverModel (server) {
        var self = this;
        self.Name = ko.observable(server.name);
        self.Price = ko.observable(server.price);
        self.SKU = ko.observable(server.sku);
    }