在剔除中自动映射相关属性 [英] Automate mapping of dependent properties in knockout

查看:77
本文介绍了在剔除中自动映射相关属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个产品选项列表,每个产品选项都有一个sku标识符,该标识符从服务器作为JSON接收.然后,我还有其他选项,这些选项取决于所选择的先决条件值,这是由product-option数组的requires数组属性定义的:

I have a list of product options each with an sku identifier that is received as JSON from the server. I then have other options which depend on prerequisite values being selected, this is defined by the requires array property of the product-option arrays:

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,
}];

然后在我的视图模型中,使用以下代码过滤可供选择的值(在大多数情况下,泛型是通用的,变量引用会根据查询需求检查所使用的内容而变化):

In my viewmodel, I then filter the values available for selection with the following code (generic for the most part, variable references change depending on what is being used to query for the requires checking):

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.availableDatabasesself.availableClusteringOptions).

Whilst my code works, it is statically typed in advance manually by me and as I add new fields I am doing a lot of copy paste as the code syntax is identical just the variables change (case in point self.availableDatabases and self.availableClusteringOptions).

将来,我们可能会(从服务器数据库中)添加一个全新的选项对象,所有这些选项对象都需要动态地进行处理,映射和创建关系.可以添加的将来的产品选项可能是例如:

In the future we may add in (from the server database) a completely new option object, that would need to be handled, mapped and relationships created, all dynamically. A future product option that could be added could be for example:

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"],
}]; 

这在自动化方面呼之欲出,特别是因为这些数据将从数据库中获取,但我不知道从何开始.

This is crying out for automation particularly as this data will be fed from a database, but i don't know where to start with this.

我已经看到了可以从json创建viewmodel的敲除映射插件,但是从文档中我不确定这将如何与我的数据结构配合使用,因为我的JSON比示例要复杂得多.

I have seen knockout mapping plugin that will create the viewmodel from json, but from the documentation i am not sure how this would tie in with my data structures as my JSON is a lot more complex than the examples.

如何自动执行此代码,以允许动态设置其他相关的需要"先决条件值?在这种情况下,基因剔除映射可以提供帮助吗?还是我需要寻找替代途径?

How can i automate this code to allow for additional dependent 'requires' prerequisite values to be set dynamically? Can knockout mapping help in this instance or do i need to look at an alternative avenue?

小提琴在这里: http://jsfiddle.net/g18c/E54YC/7/

Fiddle is here: 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);

推荐答案

此处是对提琴的快速更新,显示了如何创建自己的模型以映射数据-

Here is a quick update to your fiddle showing how you could create your own models to map data - http://jsfiddle.net/E54YC/9/

如果您想变得更加激烈并进行关系映射,您可以有很多选择,但是我会考虑前两个-

If you wanted to get more intense and have relationship mapping you have many choices, but the top two I would consider -

  1. 编写自己的自定义代码来处理需求,以及是否可以根据需求选择该代码

  1. Write your own custom code to handle requirements and whether you can select this or that depending on it's requirements

使用客户端数据库(ORM)像Breeze.js一样处理关系映射,您只需将逻辑放入视图模型中即可.

Use a client side data library (ORM) to handle it like Breeze.js where relationship mapping is handled for you and you just need to put the logic in your view model.

模型示例-

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

这篇关于在剔除中自动映射相关属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆