将 backbone.js 视图附加到现有元素上,还是将 el 插入到 DOM 中

我正在实现我的第一个实际的非教程 Backbone 应用程序,对于使用 Backbone.js 的一个方面有两个问题,我不太适应,这涉及到将视图渲染的 el注入到 DOM 中,而不是使用现有的 el元素。我想我会在这里给大家提供一些“有教育意义的时刻”,并感谢大家的帮助。

我在 web 上看到的大多数 Backbone View 示例在创建一个 View 时都会指定 tagName、 id 和/或 className,从而创建一个与 DOM 分离的 el。它们通常看起来像这样:

App.MyView = Backbone.View.extend({
tagName: 'li',
initialize: function () {
...
},
render: function () {
$(this.el).html(<render an html template>);
return this;
}
});

但是教程并不总是解释他们建议如何将呈现的 el 放入 DOM 中。我从不同的角度看过。因此,我的第一个问题是: 调用视图的呈现方法并将其 el 插入到 DOM 中的合适位置在哪里?(不一定是同一个地方)。我见过在路由器中,在视图的初始化或呈现函数中,或者仅仅在根级文档就绪函数中完成。($(function ()).我可以想象这些工作中的任何一个,但是有没有正确的方法去做呢?

其次,我开始使用一些 HTML 标记/线框,并将 HTML 部分转换为与主干视图对应的 js 模板。与其让视图呈现一个未附加的元素,并在 html 中提供一个锚点来固定它,我觉得更自然的做法是,当一个视图只有一个元素而且它不会消失时,使用一个现有的、空的包装器元素(通常是 divspan)作为 el本身。这样我就不用担心在文档中找到插入我的独立 el 的位置,它可能最终看起来像这样(注意额外的分层) :

<div id="insert_the_el_in_here">  <!-- this is all that's in the original HTML doc -->
<div id="the_el">  <!-- i used to be a backbone generated, unattached el but have been rendered and inserted -->
<!-- we're finally getting to some useful stuff in here -->
</div>
</div>

因此,我第二个问题的一部分是,对于一个基本上是静态的视图,直接使用页面 HTML 中的现有元素作为我的视图的 el有什么错吗?这样我就知道它已经在 DOM 中,在正确的位置,并且调用渲染将立即在页面上呈现视图。我可以通过将已经存在的元素作为‘ el’传递给视图的构造函数来实现这一点。这样,在我看来,我不必担心把它粘贴到 DOM 中(使问题1变得有些无意义) ,而且调用渲染将立即更新 DOM。例如。

<form>
<div someOtherStuff>
</div>
<span id="myView">
</span>
</form>


<script type="text/template" id = "myViewContents"> . . . </script>


<script type="application/javascript">
window.MyView = Backbone.View.extend( {
initialize: function () {
this.template = _.template($('#myViewContents').html());
this.render();
},
render: function () {
$(this.el).html(this.template());
return this;
}
});
$(function () {
window.myView = new MyView({ el: $('#myView').get(0) });
});
</script>

对于页面上的静态视图,这样做是否可行?也就是说,这些观点只有一个,在任何情况下都不会消失。还是有更好的办法?我意识到根据我使用视图的方式可能有不同的方法(比如,在路由器中,在父视图中,在页面加载上,等等) ,但是现在我看的是最初的页面加载用例。

谢谢

43722 次浏览

将视图附加到现有 DOM 节点的想法绝对没有错。

你甚至可以把轻轨作为一个属性放在你的视图中。

window.MyView = Backbone.View.extend( {
el: '#myView',
initialize: function () {
this.template = _.template($('#myViewContents').html());
this.render();
},
render: function () {
this.$el.html(this.template()); // this.$el is a jQuery wrapped el var
return this;
}
});
$(function () {
window.myView = new MyView();
});

我的建议是,做什么工作... 美丽的主干是,它是灵活的,将满足您的需求。

就常见模式而言,通常我发现自己有一个主视图来跟踪 over 视图,然后可能是一个列表视图和单个项视图。

就初始化而言,另一种常见的模式是使用某种 App 对象来管理内容... ..。

var App = (function ($, Backbone, global) {
var init = function () {
global.myView = new myView();
};


return {
init: init
};
}(jQuery, Backbone, window));


$(function () {
App.init();
});

就像我之前说过的,做事情真的没有错误的方法,只是做有效的事情。 :)

如果你需要更多帮助,可以在推特@jcreamer898上联系我,也可以查查@derickBailey 他是 BB 专家。

玩得开心!

您还可以将 HTMLDOMElement 对象作为选项的“ el”属性发送到视图中。

window.MyView = Backbone.View.extend( {
initialize: function () {
this.template = _.template($('#myViewContents').html());
this.render();
},
render: function () {
this.$el.html(this.template()); // this.$el is a jQuery wrapped el var
return this;
}
});
$(function () {
window.myView = new MyView({
el: document.getElementById('myView')
});
});

使用委托事件方法:

initialize: function() {
this.delegateEvents();
}

理解原因: http://backbonejs.org/docs/backbone.html#section-138靠近“设置回调,其中”

看起来这些天你也可以使用 SetElement