Backbone.View "el" 混淆

IT技术 javascript backbone.js backbone-views
2021-03-22 11:33:48

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

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

3个回答

视图 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);
    }
});

第一个视图只是创建列表项,第二个视图实际上将它们放在页面上。我认为这与backbone.js 站点上的ToDo 示例中发生的情况非常相似我认为约定是将您的内容呈现到 el 中。因此 el 用作放置模板化内容的着陆点或容器。Backbone 然后将其事件绑定到其中的模型数据。

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

@scoarescoare 由于您在实例化时添加 el 属性,因此视图本身实际上并没有比它应该知道的更多,它仍然是module化的并且能够接受您想要传递的任何 $(el) 。所以这使得它非常可重用,真的。
2021-04-23 11:33:48
我想我使用 el: $("#someElementID") 获取预先存在的元素的唯一问题是您的视图可能知道的比它应该知道的更多,因此很难重用它。请参阅“从 DOM 中分离视图...” coenraets.org/blog/2012/01/ ...
2021-05-08 11:33:48
用定义 el 的属性的一些描述更新了我的答案。
2021-05-20 11:33:48
感谢您的澄清和示例!我认为在某些情况下 el 应该是什么并不总是很清楚,开发人员必须对它有一种“感觉”。你的解释肯定有帮助!但是,有一个问题:您没有在 ItemView 中定义 el,而是在渲染函数中访问它。这会奏效吗?如果您没有明确定义它,是否有某种默认的 el ?
2021-05-21 11:33:48
默认情况下 el 是一个没有 id 或 class 的“div”标签。它是一个未绑定到页面 DOM 的 DOM 对象。通常我将它插入/附加到渲染函数或父视图的渲染函数中的页面。
2021-05-21 11:33:48

现在有点老了,但我也很困惑,所以对于到达这里的其他人来说,这个小提琴可能会有所帮助 - 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 不存在。
2021-04-24 11:33:48
@Mahi 是的,你是对的。我可能粘贴了错误的链接,抱歉。这个有效:jsfiddle.net/hRndn/127
2021-04-29 11:33:48
@Mark what 如果我使用的是像牵线木偶这样的复合架构......我还需要有视图的 el 吗?
2021-04-30 11:33:48
你的小提琴代码不起作用,因为链接应该是jsfiddle.net/hRndn
2021-05-17 11:33:48

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

嗯,这也不是很清楚。大多数情况下,可以触发视图更改的元素都在视图呈现的模板内,因此在呈现这些元素之前,这些元素还不存在。
2021-04-26 11:33:48