Backbone.js EL и шаблон в представлении - PullRequest
3 голосов
/ 26 октября 2011

Так что я очень плохо знаком с backbone.js и не очень хорош в JavaScript в целом, поэтому мне было интересно, если кто-нибудь сможет объяснить мне, почему

Я не могу определить свое свойство EL и свойство Template в моем представлении, а затем использовать this.template в моем рендере. Вместо этого я должен определить шаблон и el в моей функции рендеринга.

    var ProductView = Backbone.View.extend({
    el: $('#product-list'),

    initialize: function() { 
            this.el.html('<span style="color:white">loading...</span>'); 
    }, // end initialize


    render: function(collection) { 
    //    // assign the template 
          this.template = $('#product_template');

          // Where the template will be placed  
          this.el = $('#product-list'); 

          // Add the collection to the main object 
          this.collection = collection;

          // add tthe data to the html variable 
          var html = this.template.tmpl(this.collection.toJSON());

          // place the html in the element. 
           this.el.html(html);

           // not even sure what the hell this is. 
          return this;      
        }   // end render  

});

Ответы [ 2 ]

7 голосов
/ 27 октября 2011

Проблема не в том, как вы определяете el или template, а в том, как вы настраиваете обратный вызов. В Workspace, вашем маршрутизаторе, вы устанавливаете обратный вызов для события обновления коллекции следующим образом:

// Bind the view and collection 
// So when the collection is reset, the view executes the render method
Products.bind("reset", this.view.render); 

Проблема в том, что вы устанавливаете метод в качестве обратного вызова, но вы не предоставляете объект контекста в качестве третьего аргумента для привязки - поэтому метод вызывается, но this в методе относится к глобальному объект, не вид. Так что this.el не определено, потому что он вообще не смотрит на экземпляр представления. Попробуйте:

// Bind the view and collection 
// So when the collection is reset, the view executes the render method
Products.bind("reset", this.view.render, this.view); 

и посмотрите, как это будет.

(Я сделал jsFiddle, чтобы продемонстрировать, что el и template были установлены правильно при нормальных обстоятельствах, хотя на самом деле он не включает вышеуказанное исправление, которое трудно смоделировать без данных на стороне сервера: http://jsfiddle.net/nrabinowitz/QjgS9/)

7 голосов
/ 26 октября 2011

Вы не можете сделать это:

var ProductView = Backbone.View.extend({
    el: $('#product-list'),
    // ...

и получите что-нибудь полезное в el, так как #product-list, вероятно, даже не присутствует в DOM, когда создается ProductView; поэтому попытка использовать $('#product-list') для el - это просто классическая проблема "Я забыл использовать $(document).ready()", одетый в Backbone. Использование $('#product-list') для el должно работать, если #product-list присутствует, когда вы определяете ваш ProductView, хотя.

Вы можете сделать это, хотя:

var ProductView = Backbone.View.extend({
    el: '#product-list',
    // ...

, а затем скажите $(this.el), когда вам нужно что-то делать внутри методов представления. $(this.el) не только является обычным способом использования el, но также работает, и это очень важно.

Те же проблемы относятся к #product_template.


Глядя на ваш код, я вижу это:

// INstantiate the view 
this.view = new ProductView(); 

// Bind the view and collection 
// So when the collection is reset, the view executes the render method
Products.bind("reset", this.view.render); 

Предположительно, render запускается событием сброса. Но, и это большое, но метод render не привязан вправо this где-либо, поэтому this не будет ProductView при вызове render и this не будет есть все, что вы ожидали; следовательно, ваша причудливая «неопределенная» ошибка.

Вы можете использовать _.bindAll в своем initialize:

initialize: function() {
    _.bindAll(this, 'render');
    // ...

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

Вы также можете указать контекст (AKA this), когда звоните bind:

collection.bind('reset', this.render, this);
...