0

我正在尝试找出将元素添加到使用 ko.mapping 创建的模型中的列表的规范方法。我创建了一个 jsFiddle 来修补

javascript 类似于以下内容:

var mapping, baseModel, view_model;

mapping = {
    outer: [{
        alpha: '',
        beta: [
            {
            carotine: '',
            blockers: ''}
        ]
    }]
};

baseModel = { // add in functionality
    append_outer: function() {
        this.outer.push({});
    },
    append_beta: function(xyz) {
        this.beta.push({});
    }
};

view_model = ko.mapping.fromJS(mapping, {}, baseModel);

ko.applyBindings(view_model, $("#mapped")[0]);​

相应的 HTML在 jsFiddle 上

当我使用时,append_outer我希望将一个新元素添加到 view_model 中,该元素与第一个元素基本相同,都带有 observables。当我使用时,append_beta我希望 beta 有一个新元素[carotine: ko.observable(), blockers: ko.observable]。我还没有看到一个明显的方法来做到这一点 - 但我希望它是一个非常常见的用例。

出于显而易见的原因,示例代码没有达到我想要的效果!当然,这正是我正在修补的东西,希望能找到一些明显的东西,例如ko.mappingCreate或类似的东西。唉,没有这样的运气。

可能会提到数据模型是动态的——尽管列表中的项目总是具有与其对等节点相同的数据表示。有人可能会说,用于创建视图模型 ( mapping) 的数据是一个原型。

我将不胜感激任何想法和方向。

4

2 回答 2

1

并不是说我会这样做……而是为将映射的各个方面作为模板的类型创建一个对象。

http://jsfiddle.net/keith_nicholas/EEE6J/

一般来说,我只是用对象定义结构,然后将 json 用于数据。

于 2012-06-27T01:29:49.157 回答
0

根据基思的建议,我做了以下事情:

var mapping, baseModel, view_model;

mapping = {
    outer: [{
        alpha: '',
        beta: [
            {
            carotine: '',
            blockers: '',
            skittles: ''}
        ]}
    ]
};

baseModel = function(mapping) { // add in functionality
    var self = this;

    this._vm_prototype = mapping;

    console.log("Prototype: " + ko.mapping.toJSON(this._vm_prototype));

    self.append = function(target, proto_getter) {
        console.log("pg: " + proto_getter);
        var prototype = proto_getter(self._vm_prototype);

        console.log("Prototype: " + JSON.stringify(prototype));
        console.log("Target: " + ko.mapping.toJSON(target));

        this[target].push(ko.mapping.fromJS(prototype));
    };
};

view_model = ko.mapping.fromJS(mapping, {}, new baseModel(mapping));

ko.applyBindings(view_model, $("#mapped")[0]);​

不幸的是,这需要在 HTML 方面进行一些修改,例如添加一个新beta的必须确定它存在于原型中的哪个位置,即

<button data-bind='click: $root.append.bind($data, "beta", 
        function (proto) { return proto.outer[0].beta[0]; })'>
  Add another beta
</button>

并且对于一个outer

<button data-bind='click: append.bind($data, "outer", 
        function (proto) { return proto.outer[0]; })'>
 Add another outer
</button>

如果只是传递函数来代替函数,则该append函数可以变得更简洁outer[0].beta[0],但随后必须解析或evalthis。

从 jsFiddle AB可以看出,唯一改变的是mapping,但两者的功能都按预期工作。

同样,我试图避免重复代码,但这很难看。我很想知道如何清理这个!

于 2012-06-27T13:54:43.693 回答