2015-01-02 2 views
1

Я хочу переписать прототип модели Backbone с использованием underscore.js. Это мой код:Javascript: переписывание прототипа модели Backbone

_.extend(TableView.prototype, { 
    el: $("#" + this.id + "_div"), 
}); 

В заключение, я хочу, что по умолчанию модель прикрепляется к HTML элементу с идентификатором, равным идентификатору модели плюс «_div». Идентификатор модели - это атрибут TableViewid, и я пытаюсь получить доступ к модели, используя this. Проблема в том, что я получаю ошибку: «это неопределенно». Зачем?

PS: Я знаю, что правильным способом является расширение модели в новой. Я хочу перезаписать исходный, потому что метод extend() Backbone, похоже, не похож на наследование класса, а my_new_object instanceof TheOldModel возвращает false. Во всяком случае, я получаю ту же ошибку и с TableView.extend().

PPS: Я расширяю некоторые виды Splunk.

+1

Что вы ожидаете, что 'this' будет ссылаться? К экземпляру 'TableView'? Помните, что 'this' присваивается внутри вызова функции, но вы не имеете в виду' this' внутри любой функции (в приведенном примере). ** Изменить: **: См. [Это] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this). –

ответ

3

Когда ваш фрагмент кода оценивается, this не имеет определенного значения и установлен в зависимости от контекста. Это будет иметь смысл только в контексте экземпляра, который происходит позже.

Если вы хотите установить динамический el, обеспечивает функцию, которая будет оцениваться при создании экземпляра вида:

var TableView = Backbone.View.extend({ 
    el: function() { 
     return '#'+this.id+'_div'; 
    } 
}); 

var v = new TableView({id: 'x'}); 
console.log(v.$el.text()); 

http://jsfiddle.net/nikoshr/bcfhqq18/

Или, если вы предпочитаете, чтобы изменить прототип

TableView.prototype.el = function() { 
    return '#'+this.id+'_div'; 
} 

http://jsfiddle.net/nikoshr/bcfhqq18/2/

Наконец, следует отметить, что расширение класса с помощью Backbone устанавливает цепочку прототипов и instanceof должно быть верно при тестировании против класса-предка:

var TableView = Backbone.View.extend({ 
}); 
var DeepTableView = TableView.extend({ 
    el: function() { 
     return '#'+this.id+'_div'; 
    } 
}); 

var v = new DeepTableView({id: 'x'}); 

console.log(v instanceof Backbone.View); // true 
console.log(v instanceof TableView); // true 
console.log(v instanceof DeepTableView); // true 

http://jsfiddle.net/nikoshr/bcfhqq18/3/

+0

Ну, это работает, но я немного смущен. Почему я могу заменить атрибут 'id' на метод? И более того, когда я создаю новый 'DeepTableView', я могу переопределить значение по умолчанию' el' со статическим элементом jQuery, вместо того, чтобы назначать ему функцию. Кажется, что Javascript не имеет значения, является ли что-то методом или является атрибутом. –

+0

Я не уверен, что понимаю ваш смысл, но определение атрибута представления класса со значением выполняется, когда вам нужно одинаковое значение для всех экземпляров этого класса и с функцией, когда вам нужно другое значение для каждого экземпляра когда вы его создаете. – nikoshr

+1

Что касается того, почему это работает, это потому, что Backbone позволяет использовать эти две формы (в основном через http://underscorejs.org/#result) – nikoshr

Смежные вопросы