6

我遇到了 knockout.js 的问题,并且映射插件没有为源数据中的子数组创建模型

var data = {
    outer: [
        {
        'id': 1,
        name: 'test outer',
        inner: [{
            'id': 1,
            name: 'test inner'}]}]
};

function OuterModel(data) {
    var self = this;
    ko.mapping.fromJS(data, {}, this);

    self.fullText = ko.computed(function() {
        return self.id() + ". " + self.name();
    });
}

function InnerModel(data, parent) {
    var self = this;
    ko.mapping.fromJS(data, {}, this);

    self.fullText = ko.computed(function() {
        return self.id() + ". " + self.name() + "(" + parent + ")";
    });
}

function PageModel() {
    var self = this;
    this.data = null;
}

var mapping = {
    'outer': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        },
        create: function(options) {
            var thisModel = new OuterModel(options.data);
            return thisModel;
        }
    },
    'inner': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        },
        create: function(options) {
            var thisModel = new InnerModel(options.data);
            return thisModel;
        }
    }
};

var model = new PageModel();
model.data = ko.mapping.fromJS(data, mapping);

(这是我可以为此做的一个小回购。这里提供小提琴:http: //jsfiddle.net/msieker/6Wx3s/

简而言之,永远不会调用 InnerModel 构造函数。我已经尝试过'InnerModel'它在这个片段中的位置和'inner'映射中的位置。从我所看到的大多数情况来看,这应该可以正常工作,但显然我错过了一些东西。

任何人都有这方面的经验,可以为我指明正确的方向吗?

编辑: 根据@John Earles 的回答,我已经得到了更接近我需要的东西:

var data = {
    outer: [
        {
        'id': 1,
        name: 'test outer',
        inner: [{
            'id': 1,
            name: 'test inner'}]}]
};

var outerMapping = {
    'outer': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        },
        create: function(options) {
            var thisModel = new OuterModel(options.data);
            return thisModel;
        }
    }
};

function OuterModel(data) {
    var self = this;
    ko.mapping.fromJS(data, innerMapping, this);

    self.fullText = ko.computed(function() {
        return self.id() + ". " + self.name();
    });
}

var innerMapping = {
    'inner': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        },
        create: function(options) {
            console.log(options);
            var thisModel = new InnerModel(options.data, options.parent());
            return thisModel;
        }
    }
};

function InnerModel(data, parent) {
    var self = this;
    ko.mapping.fromJS(data, {}, this);

    self.fullText = ko.computed(function() {
        return self.id() + ". " + self.name() + "(" + parent + ")";
    });
}

function PageModel() {
    var self = this;
    this.data = null;
}

var model = new PageModel();
model.data = ko.mapping.fromJS(data, outerMapping);
ko.applyBindings(model);?

但是,parent传递给 InnerModel 的是null,这就是我追求映射插件的全部原因。文档让我相信这应该被传递options给函数的参数create,但是我得到了一个observable其值为null. 在这个方向上还有什么额外的指示吗?

4

2 回答 2

2

您没有将映射选项(定义如何映射内部)传递给 OuterModel 映射调用。

function OuterModel(data) {
    var self = this;
    ko.mapping.fromJS(data, mapping, this);

    self.fullText = ko.computed(function() {
        return self.id() + ". " + self.name();
    });
}

编辑:更新小提琴以显示父母的手动附件:

http://jsfiddle.net/jearles/6Wx3s/5/

于 2012-03-21T10:10:39.610 回答
1

前段时间我有一个非常相似的场景,在这里查看问答:Map JSON data to Knockout observableArray with specific view model type

在我的示例中,我有一个 StateViewModel,其中包含一个填充了 2 个 CityViewModel 的 observableArray,每个 CityViewModel 都包含一个填充了 2 个 StreetViewModel 的 observableArray。

然后,我希望这个视图模型结构使用敲除的映射插件从我的分层 json 数据构建。

这个小提琴给出了答案:http: //jsfiddle.net/KodeKreachor/pTEbA/2/

于 2012-04-03T21:59:14.160 回答