2014-10-23 2 views
0

У нас есть суперкласс класса Backbone View с шестью подклассами, расширяющими его. Каждый подкласс предназначен для рендеринга определенного типа модели. Сам суперкласс не очень полезен для создания экземпляра. Но было бы очень удобно иметь возможность вызвать этот конструктор суперклассов с помощью модели и вернуть ему представление о соответствующем подклассе для предоставленной модели. Можно ли это сделать с помощью магистрали?Может ли конструктор backbone.js возвращать подкласс?

+2

Как об использовании [Factory Method Pattern] (http://en.wikipedia.org/wiki/Factory_method_pattern)? Добавьте метод к базовому классу, который принимает модель в качестве аргумента и возвращает правильно подобранный подкласс вида? – naomik

+0

У вас нет легкого доступа к функции-конструктору с помощью Backbone, поэтому упростить метод на заводе-изготовителе. –

+0

Модель фабричного метода, вероятно, была бы идеальной, за исключением того, что мы хотим поддерживать обратную совместимость с существующим кодом, который просто называет «новым». (Этот абзац Просмотр суперкласса и его подклассов был единственным классом с гигантским деревом if/then/else в нем.) –

ответ

0

Хорошо, я получил его, указав функцию «конструктор», которая вычисляет, вызвана ли она непосредственно или через наследование, проверяя «templateName» - свойство, определяемое всеми моими дочерними классами. Если он вызывается напрямую, он создает новый объект желаемого типа и возвращает его; в противном случае он переходит к своему родительскому конструктору.

То, что я узнал сегодня: это удобная функция JS, которая, если конструктор возвращает объект, этот объект заменяет «это» и становится новым объектом.

Canonical doc on the JS new() function

Мой конструктор выглядит следующим образом:

constructor: function(options){ 

// without a model we can't know what class to be. 
if (_.isUndefined(options) || _.isUndefined(options.model) || ! options.model.has('type')) 
    throw new Error('new ThingView() called without a valid model.'); 

// Because we're replacing ourselves with a subclass, constructor will execute twice. 
if (! this.templateName) { 
    // first time through: replace ourselves with a child 
    var viewName = 'AssetAttributeView_' + options.model.get('type'); 
    return new Views[viewName](options); // replace ourselves with one of these 

} else { 
    // second time through: apply our parent's constructor. 
    Backbone.View.apply(this, arguments); 
} 
} 
Смежные вопросы