【问题标题】:Automate mapping of dependent properties in knockout在剔除中自动映射依赖属性
【发布时间】:2013-10-17 18:26:23
【问题描述】:

我有一个产品选项列表,每个选项都带有一个从服务器作为 JSON 接收的 sku 标识符。然后,我有其他选项取决于选择的先决条件值,这是由 product-option 数组的 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 和 @ 987654326@).

将来我们可能会(从服务器数据库)添加一个全新的选项对象,它需要动态处理、映射和创建关系。例如,可以添加的未来产品选项可能是:

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);

【问题讨论】:

  • 更具体一点 - 你是什么意思你如何映射它?您是否有正在访问的服务器端点并从中获取一些数据?
  • 我需要尽可能自动化这段代码,有很多重复。从文档中我相信映射将从 json 创建视图模型,但我的情况比任何示例都复杂,所以不确定它是否可能,或者我应该寻找替代方法
  • 听起来不像是个混蛋,但与使用它的人数相比,您使用的模型非常轻巧。您可以使用映射插件,也可以在客户端创建自己的模型以供重复使用。
  • 主要目的是使其动态化,因为数据将来自数据库。我的问题是如何在添加其他字段时映射requires 功能,这将根据服务器作为 JSON 发送的内容而动态出现。我已经阅读了关于 ko 映射的内容,但我不确定如何开始使用我的代码,并且非常感谢一些指导。

标签: knockout.js knockout-mapping-plugin


【解决方案1】:

这里是您的小提琴的快速更新,展示了如何创建自己的模型来映射数据 - http://jsfiddle.net/E54YC/9/

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

  1. 编写您自己的自定义代码来处理需求以及是否可以根据需求选择这个或那个

  2. 使用客户端数据库 (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);
}

【讨论】:

  • 感谢@PW Kad,所以如果我理解正确,更好的方法可能是编写我们自己的绑定机制?不确定它是否清楚,但实际的产品选项类型将是动态的(不仅仅是内容),我的意思是可能会发送一个全新的产品选项数组,即 managemenOption []。我将更新我的问题以避免混淆。感谢 Breeze 的提示,我是 javascript 新手,这样的学习很有用
  • 我已经尽我所能回答了您关于映射的问题,如果您有与技术相关的架构问题,您可以使用或构建您已经尝试过但找不到解决方案来考虑标记这个已解决并创建一个新问题,详细说明您的问题。继续将问题链接到完全不相关的问题上是没有用的
  • 尊敬的我的问题是并且一直是从一开始,关于动态自动映射属性相对于过滤的可用选项。您的回答很有用,非常感谢,但没有解决我的问题。
  • 映射插件就是这样做的,它动态映射所有内容。不知道你需要多少更好的答案:)
  • 好吧,我承认:) 睡在上面并重新阅读我的问题后,我的问题得到了解答,因为我需要使用映射器。我已经使用 ko.mapper 并在此处发布了具体问题stackoverflow.com/questions/19447458/…
猜你喜欢
  • 2023-03-14
  • 2017-02-14
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多