Backbone.js просмотр наследования - PullRequest
40 голосов
/ 12 октября 2011

У меня есть вид с именем Pannel, который является просто фоном с кнопкой закрытия. Я хочу расширить эту точку зрения до вида с именем PannelAdvanced. Как бы я сделал это с backbone.js?

Прямо сейчас все примеры имеют Backbone.View.Extend, но они просто расширяются Backbone.View; Я хочу продлить мой PannelView.

Ответы [ 3 ]

100 голосов
/ 12 октября 2011

Самый простой способ наследовать представление - это делать то, что другие люди уже предложили в комментариях:

var Pannel = Backbone.View.extend({
});

var PannelAdvanced = Pannel.extend({
});

Но, как вы отметили в своих комментариях, если у вас есть метод инициализации в Pannel, тогда он не будет вызван, если у вас также есть метод инициализации в PannelAdvanced, поэтому вы должны явно вызывать метод инициализации Pannel:

var Pannel = Backbone.View.extend({
   initialize: function(options){
      console.log('Pannel initialized');
      this.foo = 'bar';
   }
});

var PannelAdvanced = Pannel.extend({
   initialize: function(options){
      Pannel.prototype.initialize.apply(this, [options])
      console.log('PannelAdvanced initialized');
      console.log(this.foo); // Log: bar
   }
});

Это немного уродливо, потому что если у вас много просмотров,унаследуйте от Pannel, тогда вам придется не забывать вызывать инициализацию Pannel для всех из них.Хуже того, если у Pannel сейчас нет метода инициализации, но вы решили добавить его в будущем, вам нужно будет перейти ко всем унаследованным классам в будущем и убедиться, что они вызывают инициализацию Pannel.Итак, вот альтернативный способ определения Pannel, так что ваши унаследованные представления не должны вызывать метод инициализации Pannel:

var Pannel = function (options) {

    // put all of Panel's initialization code here
    console.log('Pannel initialized');
    this.foo = 'bar';

    Backbone.View.apply(this, [options]);
};

_.extend(Pannel.prototype, Backbone.View.prototype, {

    // put all of Panel's methods here. For example:
    sayHi: function () {
        console.log('hello from Pannel');
    }
});

Pannel.extend = Backbone.View.extend;


// other classes inherit from Panel like this:
var PannelAdvanced = Pannel.extend({

    initialize: function (options) {
        console.log('PannelAdvanced initialized');
        console.log(this.foo);
    }
});

var pannelAdvanced = new PannelAdvanced(); //Log: Pannel initialized, PannelAdvanced initialized, bar
pannelAdvanced.sayHi(); // Log: hello from Pannel
29 голосов
/ 12 октября 2011

Это одна из причин, по которой мне так нравится использовать Coffeescript.Такие вещи, как наследование, намного приятнее.Чтобы добавить правильный ответ @ JohnnyO, я могу сказать то же самое в Coffeescript:

class Panel extends Backbone.View
    initialize: ->
        console.log 'Panel initialized'
        @foo = 'bar'

class PanelAdvanced extends Panel
    initialize: ->
        super
        console.log 'PanelAdvanced initialized'
        console.log @foo
8 голосов
/ 12 марта 2013

Чтобы еще немного прокрутить:

Мне понравился подход @ JohnnyO, но я хотел подтвердить, что получившийся вид все еще способен делать все, что должен.Учитывая его подход, я не подозревал, что будут какие-то проблемы, но я хотел быть более уверенным.

Итак, я потратил минуту и ​​адаптировал набор тестов Backbone.js Views на метод множественного наследования @JohnnyO предлагает.

Вы можете запустить результаты в http://jsfiddle.net/dimadima/nPWuG/. Все тесты пройдены.

Мои базовые и расширенные представления:

var RegularView = function (options) {
  // All of this code is common to both a `RegularView` and `SuperView`
  // being constructed.
  this.color = options && (options.color || 'Green');

  // If execution arrives here from the construction of
  // a `SuperView`, `Backbone.View` will call `initialize`
  // that belongs to `SuperView`. This happens because here
  // `this` is `SuperView`, and `Backbone.View`, applied with
  // the current `this` calls `this.initialize.apply(this, arguments)`
  Backbone.View.apply(this, arguments)
};

RegularView.extend = Backbone.View.extend;

_.extend(RegularView.prototype, Backbone.View.prototype, {
  // Called if a `RegularView` is constructed`,
  // Not called if a `SuperView` is constructed.
  initialize: function () {
    console.log('RegularView initialized.');
  },

  say_hi: function() {
    console.log('Regular hi!');
  }

});

var SuperView = RegularView.extend({
  // Called if a `SuperView` is constructed`,
  // Not called if a `RegularView` is constructed.
  initialize: function(options) {
    console.log('SuperView initialized.')
  },

  say_hi: function() {
    console.log('Super hi!');
  }
})

ДляВ тестовом наборе я взял последние тесты GitHub и заменил вхождения Backbone.View на RegularView.Затем в тестах используются RegularView и результаты RegularView.extend(), чтобы убедиться, что оба делают то, что должны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...