backbone.js просмотр наследования.`this` разрешение в родительском - PullRequest
7 голосов
/ 07 июня 2011

У меня есть случай, в котором используется наследование представления, и мой код выглядит по существу следующим образом:

parentView = Backbone.View.extend({
    events: {
        "some event": "business"
    },
    initialize: function(){
        _.bindAll(this);
    },
    business: function(e){
        ...
        this.someFunc && this.someFunc();
        ...
     }
});

childView = parentView.extend({
    events: {
        ...
    },
    constructor: function(){
       this.events = _.extend( {}, parentView.prototype.events, this.events );
       parentView.prototype.initialize.apply( this );
    },
    initialize: function(){
       _.bindAll(this);
    },
    someFunc: function(){
       ...
    }
});

Обновление: перенесено this.events расширение в конструктор.

Мой дочерний вид имеет someFunc в нем и во время некоторой бизнес-функции в родительском представлении она должна вызывать эту функцию, если она существует.Если this правильно установлено на childView, тогда this.someFunc должно существовать.Однако это не то поведение, которое я испытываю.

Во время функции initialize (в родительском элементе) this действительно установлено в дочернее представление.Однако при срабатывании some event функция business вызывается с this, установленным на parentView.

Ответы [ 3 ]

9 голосов
/ 07 июня 2011

Вы пытались расширить this.events в конструкторе, а не в функции инициализации?Если вы делаете это при инициализации, вы слишком поздно;Делегирование событий для функции business уже настроено в конструкторе и будет указывать на parentView (см. вызов this.delegateEvents(); в конструкторе Backbone.View).

Обновлен с рабочим примером:

ParentView = Backbone.View.extend({
    name: 'ParentView',
    events: {
        "event": "business"
    },
    business: function(e){
        this.someFunc && this.someFunc();
    }
});

ChildView = ParentView.extend({
    name: 'ChildView',
    events: {
    },
    constructor: function(){
       this.events = _.extend( {}, ParentView.prototype.events, this.events );
       console.debug( this.events );
       ParentView.prototype.constructor.apply( this, arguments );
    },
    someFunc: function(){
        console.debug('someFunc; this.name=%s', this.name);
    }
});

child = new ChildView();
$( child.el ).trigger('event');
// logs 'this' in 'someFunc'; the name is 'ChildView'.
2 голосов
/ 07 июня 2011

На самом деле, я не знаю, решит ли это ваше дело, но я обычно делаю это: this.constructor.__super__.initialize.apply(this, arguments); и работает как шарм. Мое решение совершенно неверно.Вот почему:

var Model1 = Backbone.Model.extend({
  method: function () {
    // does somehting cool with `this`
  }
});

var Model2 = Model1.extend({
  method: function () {
    this.constructor.__super__.method.call(this);
  }
});

var Model3 = Model2.extend({
  method: function () {
    this.constructor.__super__.method.call(this);
  }
});

var tester = new Model3();

// Boom! Say hallo to my little stack-overflowing recursive __super__ call!
tester.method();

Звонок на this.constructor.__super__ в Model2::method разрешится (барабанная дробь) Model2::method.

Всегда использовать ExplicitClassName.__super__.methodName.call(this, arg1, arg2 /*...*/) или Coffee-script super.

0 голосов
/ 07 июня 2011

Вы можете решить эту проблему, добавив следующую строку в метод инициализации дочернего элемента:

_.bind(this.business, this)

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

Что происходит, так это то, что метод будет использовать контекст области, в которой он был определен, если не указано иное. initialize сказано использовать контекст потомка при вызове parentView.prototype.initialize.apply(this), потому что вы передаете childView со ссылкой this на метод apply.

Вы можете привязать бизнес-метод к контексту дочернего процесса, используя метод underscore.js bind, как описано выше.

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