骨干。查看“ el”混乱


97

应该如何el处理视图?必须设置它,否则事件不会触发(请参阅此处)。

但是它应该是页面上已经存在的元素吗?在我的应用程序中,我将(jQuery模板)模板渲染到Fancybox中。el在那种情况下应该是什么?


11
我以为-我是唯一一个喜欢这个el东西的人。
Yugal Jindle 2013年

el就像gf。没有人能完全理解它们。
Mahi

Answers:


121

视图el是所有事件绑定发生的地方。您不必使用它,但是如果您希望骨干触发事件,则需要在el上进行渲染工作。视图el是DOM元素,但不一定是预先存在的元素。如果您不从当前页面中拉出一个页面,则会创建该页面,但是如果您想看到它做任何事情,则必须将其插入页面。

一个例子:我有一个创建单个项目的视图

window.ItemView = Backbone.View.extend({
    tagName: "li", //this defaults to div if you don't declare it.
    template: _.template("<p><%= someModelKey %></p>"),
    events: {
         //this event will be attached to the model elements in
         //the el of every view inserted by AppView below
        "click": "someFunctionThatDoesSomething"
    },
    initialize: function () { 
        _.bindAll(this, "render");
        this.render();
    },
    render: function () {
        this.el.innerHTML = this.template(this.model.toJSON());
        return this;
    }
});
window.AppView = Backbone.View.extend({
    el: $("#someElementID"), //Here we actually grab a pre-existing element
    initialize: function () { 
        _.bindAll(this, "render");
        this.render(new myModel());
    },
    render: function (item) { 
        var view = new ItemView({ model: item });
        this.el.append(view.render().el);
    }
});

第一个视图仅创建列表项,第二个视图实际上将它们放置在页面上。我认为这非常相似,与ribs.js网站上的ToDo示例中发生的情况类似。我认为惯例是使您满意。因此,el可作为登陆位置或放置模板内容的容器。然后,骨干将其事件绑定到其中的模型数据。

当你创建一个视图中可以使用操纵EL在四个方面el:tagName:className:,和id:。如果没有一个被声明,则el默认为不带id或class的div。此时它也未与页面关联。您可以使用tagName将标签更改为其他名称(例如tagName: "li",将为您提供el <li></li>)。您可以同样设置el的id和class。Still el还不是您网页的一部分。el属性使您可以对el对象进行非常精细的操作。大多数时候,我使用el: $("someElementInThePage")实际上将您对视图所做的所有操作绑定到当前页面。否则,如果您希望查看在视图中所做的所有艰苦工作,这些内容会显示在页面上,则需要将其插入/追加到视图中其他位置的页面(可能是在渲染中)。我喜欢将el视为所有视图操纵的容器。


感谢您的说明和示例!我认为在某些情况下el应该是什么并不总是很清楚,因此开发人员必须对此感到“满意”。您的解释当然有帮助!不过,有一个问题:您没有在ItemView中定义el,而是在render函数中访问它。这样行吗?如果您未明确定义它,是否会有某种默认的el?
Manuel Meurer

3
默认情况下,el是没有id或class的“ div”标签。它是一个未绑定到页面DOM的DOM对象。通常,我将其插入/追加到父视图的render函数或render函数的页面中。
LeRoy

用定义el的属性的一些描述更新了我的答案。
LeRoy

5
我猜想,用el捕获一个预先存在的元素的唯一问题是:$(“#someElementID”)是您的视图可能知道的多于其应有的知识,因此很难重用它。参见“从DOM解耦视图...” coenraets.org/blog/2012/01/…–
Scott Coates

@scoarescoare因为在实例化时添加了el属性,所以视图本身实际上并不了解更多信息,它仍然是模块化的,并且能够接受要传递的任何$(el)。因此,这确实使其可重用。
传记作者2012年

6

现在有点老了,但是我也很困惑,所以对于其他来到这里的人来说,这个小提琴可能会有所帮助-http://jsfiddle.net/hRndn/2/

var MyView = Backbone.View.extend({

    events: {
        "click .btn" : "sayHello",
    },

    sayHello : function() {
        alert("Hello");
    },


    render : function() {
        this.$el.html("<input type='button' class='btn' value='Say Hello'></input>");

    }
});

$(function() {
    myView = new MyView({el:"#parent_id"});
    myView.render();
});

我遵循这种模式,但愿我没有。要销毁视图并删除绑定,主干的约定为view.remove()。这会破坏$ el并将其从DOM中删除,因此当您需要再次显示视图时,$ el不存在。
JJ 2013年

@Mark如果我使用的是木偶之类的复合建筑...,我还需要查看景观吗?
2013年

您的小提琴代码不起作用,因为链接应该是jsfiddle.net/hRndn
Izzy

@Mahi是的,你是对的。我可能粘贴了错误的链接,对不起。此作品有效:jsfiddle.net/hRndn/127
Izzy

1

您希望您的“ el”引用一个包含子元素的元素,该子元素具有触发视图更改的任何事件。可以和“ body”标签一样宽。


嗯,那也没有真正清除它。大多数情况下,可能触发我的视图更改的元素都在视图渲染的模板内部,因此在渲染之前,这些元素尚不存在。
Manuel Meurer
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.