2013-09-04 2 views
3

Я не уверен, что этот вопрос специфичен для Backbone.js. У меня есть модель со следующей визуализацией функции:Сохранение «этой» внутренней функции обратного вызова

render: function() { 
    var self = this; 
    this.$el.empty(); 
    this.model.fetch({ 
     success: function() { 
      self.$el.append(self.template(self.model.attributes));  
     } 
    }); 

    return this; 
} 

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

+0

Для небольших обратных вызовов без внутренних обратных вызовов, которые можно использовать function.prototype.bind (или аналогичные альтернативы), но для больших кусков кода я рекомендую придерживаться «я» или «того», потому что поскольку эти лексико-переменные переменные продолжают работать даже для вложенных обратных вызовов. – hugomg

ответ

6

Есть ли способ я могу сохранить первоначальную ссылку на это без сохранения в другой переменной?

Да, это разумный вариант использования для proxy method

this.model.fetch({ 
    success: $.proxy(function() { 
     this.$el.append(this.template(this.model.attributes));  
    }, this) 
}); 

В качестве альтернативы вы можете использовать bind метод Underscore в:

this.model.fetch({ 
    success: _.bind(function() { 
     this.$el.append(this.template(this.model.attributes));  
    }, this) 
}); 
+1

с $ .proxy вам больше не нужно. используйте это в обратном вызове успеха. –

+0

И 'self' - ужасное имя для таких вещей из-за наличия' window.self'. –

+2

@muistooshort, фактически 'self' - очень хороший выбор. Это общий и описательный. Просто потому, что окно имеет свойство по умолчанию 'self', не означает, что вы не должны использовать' self' в других областях. – zzzzBov

6

Используйте функцию Function.prototype.bind, чтобы связать ваш объект с переменной this внутри функции.

render: function() { 
    this.$el.empty(); 
    var successFunc = function() { 
       this.$el.append(this.template(this.model.attributes));  
    }; 

    this.model.fetch({ 
     success: successFunc.bind(this) 
     } 
    }); 

    return this; 
} 
+2

'bind' не обратно совместим,' $ .proxy' есть. – zzzzBov

+1

Хорошая точка. Я оставлю свой ответ тем разработчикам, которые не используют jQuery. Обратите внимание, что реализация 'bind' достаточно проста и предоставляется на ссылке MDN, если вы не хотите использовать библиотеку, которая ее предоставляет. –

+1

@zzzzBov: Но '_.bind' будет более идиоматичным в приложении Backbone. –

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