2014-02-01 4 views
0

Я не могу запустить рендеринг HTML из шаблона поддерева. Вот код и погрешность:Trouble running underscore templates

//Code 

class QuestionView extends Backbone.View { 
    template:(data:any) => string = null; 
    $el = $root; 

    constructor(options?:any, question?:Question) { 
     super(options); 
     this.model = question; 
     var q = this; 
     require(["text!add-new-question.html"], 
      function (html) { 
       q.template = _.template(html); 
      } 
     ); 
    } 

    render() { 
     var data = this.model.toJSON(); 
     var html = this.template(data); 
     this.$el.html(html); 
     return this; 
    } 
} 

class SurveyView extends Backbone.View{ 
    tagName = "div"; 
    template:(data:any) => string = null; 
    $el = $root; 

    constructor(options?:any, survey?:Survey){ 
     super(options); 
     this.template = _.template("<div ><%= enlistQuestions %></div>"); 
    } 

    enlistQuestions():string{ 
     var questions = ""; 
     _.each(this.collection.models, function(question:Question){ 
      var view = new QuestionView(null,question); 
      questions += view.template(view.model.toJSON()); // This is line for which the error is shown. 
     }); 
     return questions; 
    } 
} 


//Error 
Uncaught TypeError: Property 'template' of object #<QuestionView> is not a function Main.ts:63 
(anonymous function) Main.ts:63 
j.each.j.forEach underscore.js:79 
SurveyView.enlistQuestions Main.ts:61 
SurveyView.render Main.ts:69 
SurveyView Main.ts:56 
(anonymous function) Main.ts:80 
+0

@muistooshort Спасибо! См. Обновление. – EternallyCurious

+0

Это вызов 'require' call async? Кажется, что 'QuestionView' получает свойство' template'. Ваша структура кода нечетна, обычно вы можете сказать 'view.render()' вместо того, чтобы взаимодействовать с 'view.template', таким образом, вы будете работать с узлами DOM и событиями. Похоже, вы работаете со всем, как строки HTML, так что вы выбрали всю обработку событий DOM в представлении, и это очень странно, что нужно делать в приложении Backbone. –

+0

@muistooshort Спасибо за исправление. – EternallyCurious

ответ

0

Похоже, вы используете «текстовый» плагин для плагинов AMD. Если нет, не принимайте во внимание этот ответ.

Этот плагин загружает ресурс асинхронно, а функция, переданная в оператор require, вызывается обратно после загрузки файла.

Похоже, что Main пытается использовать свойство template в экземпляре QuestionView до того, как обратный вызов имеет шансы его создать, следовательно, ошибка.

Текстовый модуль создает объект XHR и вызывает открытый набор. Асинхронный флаг равен true. Вы должны установить для этого флага значение false. Единственный способ, которым это возможно, - использовать обратный вызов onXhr и снова вызвать OPEN, установив флаг async в false.

requirejs.config({ 
    config: { 
     text: { 
      onXhr: function (xhr, url) { 
       // This callback is invoked AFTER open but before send. 
       // Call open again with the async flag turned off. 
       // Not this will also clear any custom headers 
       xhr.open('GET', url, /*async*/ false); 
       // xhr.setRequestHeader('header', 'value'); 
      } 
     } 
    } 
}); 

Как было отмечено выше, любой пользовательский HTTP заголовок, добавляемый в текстовом модуле будут удалены, когда вы повторно вызвать открытый, но, глядя на их код там не появляется, чтобы быть какой-либо способ подачи дополнительных заголовков в их «получить».