简体   繁体   English

Backbone.js视图中的EL和模板

[英]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 所以我对backbone.js很新,而且一般不太擅长JavaScript,所以我想知道是否有人可以向我解释为什么

I cannot define my EL property, and Template property in my view, and then use this.template in my render. 我无法在我的视图中定义我的EL属性和Template属性,然后在我的渲染中使用this.template。 Instead I have to define the template and el in my render function. 相反,我必须在我的渲染功能中定义模板和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  

});

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; 并且在el获得任何有用的东西,因为#product-list在构建ProductView时可能甚至不存在于DOM中; so trying to use $('#product-list') for el is simply the classic "I forgot to use $(document).ready() " problem dressed up in Backbone. 因此尝试使用$('#product-list')来表示el只是经典的“我忘了在Backbone中使用$(document).ready() ”问题。 Using $('#product-list') for el should work if #product-list is around when you define your ProductView though. 如果在定义 ProductView时, #product-list即将使用,则使用$('#product-list')表示el

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. 然后在需要在视图方法中执行操作时说$(this.el) Not only is $(this.el) the usual way of using el but it also works and that's sort of important. $(this.el)不仅是使用el的常用方式,而且它也有效,而且非常重要。

The same issues apply to #product_template . 同样的问题适用于#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. 据推测, render是由重置事件触发的。 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; 但是,这是一个很大的,但是,在render方法未绑定到正确的this任何地方,所以this不会是ProductView时候render被调用, this不会有什么,你希望它; hence your bizarre "undefined" error. 因此你的奇怪的“未定义”错误。

You could use _.bindAll in your initialize : 您可以在initialize使用_.bindAll

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 : 您也可以提供上下文(AKA this )当你调用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. 问题不在于您定义eltemplate ,而在于您如何设置回调。 In Workspace , your router, you're setting the callback for your collection refresh event like this: 在您的路由器Workspace ,您正在为集合刷新事件设置回调,如下所示:

// 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. 问题是,你设置的方法作为回调,但你不能提供一个上下文对象作为第三个参数绑定-这样的方法被调用,但是this在方法指的是全局对象, 不是视图。 So this.el is undefined, because it's not looking at the view instance at all. 所以this.el是未定义的,因为它根本没有查看视图实例。 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/ ) (我做了一个jsFiddle来证明eltemplate在正常情况下是正确设置的,虽然它实际上并没有包含上面的修复,如果没有服务器端数据很难模拟: http//jsfiddle.net / nrabinowitz / QjgS9 /

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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