Отображение Knockout.js не связывает дочерние модели - PullRequest
6 голосов
/ 21 марта 2012

У меня проблема с 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'. Судя по большинству сообщений о том, что я видел, это должно сработать, но, очевидно, я что-то упустил.

Кто-нибудь имеет опыт с этим, который может направить меня в правильном направлении?

EDIT: Основываясь на ответе @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. Какие-нибудь дополнительные указатели в этом направлении?

Ответы [ 2 ]

2 голосов
/ 21 марта 2012

Вы не передаете свои параметры отображения (которые определяют, как отобразить inner) в вызов отображения OuterModel.

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

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

EDIT: обновлена ​​скрипта для отображения ручного вложения родителя:

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

1 голос
/ 04 апреля 2012

Некоторое время назад у меня был очень похожий сценарий, посмотрите здесь вопросы и ответы: Сопоставьте данные JSON с Knockout observableArray с определенным типом модели представления

В моем примере у меня естьStateViewModel, который содержит массив observableArray, заполненный двумя объектами CityViewModel, а каждый объект CityViewModel содержит массив observableArray, заполненный двумя объектами StreetViewModels.

Затем я хотел, чтобы структура этой модели представления была построена из моих иерархических данных json с использованием плагина отображения нокаута.

Эта скрипка отображает ответ: http://jsfiddle.net/KodeKreachor/pTEbA/2/

...