позвоночник.Яш структурирование вложенных представлений и моделей


через хребет.js:

у меня есть модель верхнего уровня, которая содержит 2 атрибута и 2 вложенные модели, ModelB и ModelC. Модельв и модельки по 2 атрибуты следующим образом:

ModelA
    attributeA1
    attributeA2
    ModelB
        attributeB1
        attributeB2
    ModelC
        attributeC1
        attributeC2

существует ViewA для ModelA и ViewB для ModelB. Функция рендеринга ViewA помещает новый div на тело, в то время как рендеринг ViewB создает h1. Инициализация ViewA вызывает рендер ViewB для вставки этого h1 в новый div. Обоснование этого разделения заключается в том, что h1 может измениться и потребовать повторного рендеринга независимо от ViewA.

ViewA
    initialise: 
        //call ViewA's own render function
        this.render() 

        //call ViewB's render function that further modifies the $("#new") div created earlier.
        $("#new").append(ViewB.render().el)

    //ViewA's own render function
    render: //place <div id="new"></div> onto 'body'

ViewB
    render: //create a <h1></h1>
    funcB1: //can this access it's parent ModelA's attributes and other objects?

Q1: ViewB имеет функцию funcB1. Может ли эта функция получить доступ к атрибутам родительской модели? Атрибуты, такие как attributeA1, или даже attributeC1 (который был бы родным братом/двоюродным братом)?

Q2: как дальнейшее расширение до Q1, может ли funcB1 получить доступ к элементам DOM, связанным с ViewA? (в этом примере, #new div?)

Q3: в общем, как я могу определить ассоциации между представлениями и Модели, как описано выше, чтобы все связывалось правильно?

Я понимаю, что этот вопрос несколько абстрактен, но любой ценит любую помощь или рекомендации.

5 71

5 ответов:

чтобы иметь возможность достигать атрибутов на связанных моделях, модель должна иметь какие-то знания о том, с какими моделями она связана. Позвоночник.js не имеет неявного отношения к отношениям или вложенности, что означает, что вы должны сами убедиться, что модели имеют знания друг о друге. Чтобы ответить на ваши вопросы, один из способов сделать это-убедиться, что каждая дочерняя модель имеет атрибут "родитель". Таким образом, вы можете пройти вложенность сначала до родителя, а затем до любых братьев и сестер, которые вы знаю.

чтобы быть более конкретным с вашими вопросами. При инициализации modelA вы, вероятно, создаете modelB и modelC, я бы предложил установить ссылку на родительскую модель при этом, например:

ModelA = Backbone.Model.extend({

    initialize: function(){
        this.modelB = new modelB();
        this.modelB.parent = this;
        this.modelC = new modelC();
        this.modelC.parent = this;
    }
}

таким образом, вы можете достичь родительской модели в любой функции, модели детей, называя это.родитель.

Что касается ваших представлений, при выполнении вложенных базовых представлений мне проще позволить каждому представлению представлять один HTML-тег, используя опцию tagName вид. Я бы написал ваши взгляды так:

ViewA = Backbone.View.extend({

    tagName: "div",
    id: "new",

    initialize: function(){
       this.viewB = new ViewB();
       this.viewB.parentView = this;
       $(this.el).append(this.viewB.el);
    }
});

ViewB = Backbone.View.extend({

    tagName: "h1",

    render: function(){
        $(this.el).html("Header text"); // or use this.options.headerText or equivalent
    },

    funcB1: function(){
        this.model.parent.doSomethingOnParent();
        this.model.parent.modelC.doSomethingOnSibling();
        $(this.parentView.el).shakeViolently();
    }

});

затем в вашем коде инициализации приложения (например, в вашем контроллере) я бы инициировал ViewA и поместил его элемент внутри элемента body.

общий ответ на вопрос "Могу ли я" всегда "да, пока вы готовы написать код."За основу-обеспечить строгое разделение модели и представления. Если B1 имеет ссылку на A1, а A1 имеет ссылку на C1, то вы полностью способны создавать методы и устанавливать правила, с помощью которых B1 может изменять A1 и C1 и т. д.

представления должны быть настроены для получения событий CRUD от их соответствующих моделей. Если пользователь что-то делает с B1view, который изменяет B1model, и B1model в свою очередь изменяет A1model, то A1model должен генерировать событие, которое a1view получает и вызывает повторную визуализацию A1view, и так далее. Это должно произойти как по волшебству. (На практике требуется некоторое время, чтобы правильно использовать магию, но я обнаружил, что позвоночник действительно силен. И BackboneRelational помогает с такими вещами, как то, что вы описываете здесь.)

вышеуказанное решение находится на правильном пути, но есть некоторые проблемы.

initialize: function(){
  this.viewB = new ViewB();
  this.viewB.parentView = this;
  $(this.el).append(this.viewB.el);    
}

в основном, модель toJSON () теперь возвращает устаревшие данные. Я выложил решение этой проблемы костяк.плагин JS. Вы можете использовать его.

вы можете использовать некоторые расширения, Backbone-Forms https://github.com/powmedia/backbone-forms например. Чтобы следовать вашему варианту использования, определите схему следующим образом:

var ModelB = Backbone.Model.extend({
    schema: {
        attributeB1: 'Text',
        attributeB2: 'Text'
    }
});

var ModelC = Backbone.Model.extend({
    schema: {
        attributeC: 'Text',
    }
});

var ModelA = Backbone.Model.extend({
    schema: {
        attributeA1: 'Text',
        attributeA2: 'Text',
        refToModelB: { type: 'NestedModel', model: ModelB, template: 'templateB' },
        refToModelC: { type: 'NestedModel', model: ModelC, template: 'templateC' }
    }
});

посмотрите на https://github.com/powmedia/backbone-forms#customising-templates для частичных шаблонов.

важные части здесь type: 'NestedModel' и template: 'templateXXX'.

этот плагин имеет некоторые ограничения, но вы можете посмотреть на другие по https://github.com/documentcloud/backbone/wiki/Extensions%2C-Plugins%2C-Resources.

есть магистральный плагин Backbone-relational.JS код, который обеспечивает один-к-одному, один-ко-многим и многие-к-одному отношения между моделями для позвоночника.

Я думаю, что это JS будет выполнять ваши потребности. Вист BackboneRelational для получения дополнительной документации.