简体   繁体   中英

Backbone.js EL and Template in the View

So i'm very new to backbone.js and not so good at JavaScript in general, so I was wondering if someone could explain to me why

I cannot define my EL property, and Template property in my view, and then use this.template in my render. Instead I have to define the template and el in my render function.

    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  

});

You can't do this:

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

and get anything useful in el as #product-list probably isn't even present in the DOM when your ProductView is built; so trying to use $('#product-list') for el is simply the classic "I forgot to use $(document).ready() " problem dressed up in Backbone. Using $('#product-list') for el should work if #product-list is around when you define your ProductView though.

You can do this though:

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

and then say $(this.el) when you need to do things inside your view methods. Not only is $(this.el) the usual way of using el but it also works and that's sort of important.

The same issues apply to #product_template .


Looking at your code I see this:

// 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); 

Presumably the render is being triggered by the reset event. But, and this is a big but, the render method isn't bound to the right this anywhere so this won't be the ProductView when render is called and this won't have anything that you expected it to; hence your bizarre "undefined" error.

You could use _.bindAll in your initialize :

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

but usually you'd want to give the view a collection when you create it and the view would bind itself to the events so your structure will still be a bit odd.

You can also supply a context (AKA this ) when you call bind :

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

The problem isn't in the way you're defining el or template , it's in how you're setting the call back. In Workspace , your router, you're setting the callback for your collection refresh event like this:

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

The problem is, you're setting a method as a callback, but you're not providing a context object as the third argument to bind - so the method is called, but this in the method refers to the global object, not the view. So this.el is undefined, because it's not looking at the view instance at all. Try:

// 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); 

and see how that goes.

(I made a jsFiddle to demonstrate that the el and template were set properly under normal circumstances, though it doesn't actually include the fix above, which is hard to mock up without the server-side data: http://jsfiddle.net/nrabinowitz/QjgS9/ )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM