Javascript 将backbone.js 视图附加到现有元素与将el 插入DOM
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10746706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
attaching backbone.js views to existing elements vs. inserting el into the DOM
提问by Ben Roberts
I am implementing my first actual non-tutorial Backbone app, and have 2-ish questions about an aspect of using using backbone.js that isn't settling very well with me, which relates to injecting a view's rendered el
into the DOM vs. using an existing element for el
. I suspect I will provide you all with a few "teachable moments" here, and appreciate the help.
我正在实现我的第一个实际的非教程 Backbone 应用程序,并且有两个关于使用 Backbone.js 的问题,这对我来说不是很好,这涉及将视图的渲染el
注入 DOM 与使用的现有元素el
。我怀疑我会在这里为大家提供一些“可教的时刻”,并感谢您的帮助。
Most Backbone View examples I see in the web specify tagName, id and/or className, when creating a View and thereby create an el that is unattached from the DOM. They typically look something like:
我在网上看到的大多数主干视图示例在创建视图时都指定了 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;
}
});
But the tutorials don't always get around to explaining how they recommend getting the rendered el into the DOM. I've seen it a few different ways. So, my first question is: where is the appropriate place to call a view's render method and insert its el into the DOM? (not neccessarily one and the same place). I've seen it done in a router, in the view's initialize or render functions, or just in a root level document ready function. ( $(function ()
) . I can imagine that any of these work, but is there a right way to do it?
但是教程并不总是解释他们建议如何将渲染的 el 放入 DOM。我已经看到了几种不同的方式。所以,我的第一个问题是:调用视图的 render 方法并将其 el 插入 DOM 的合适位置在哪里?(不一定是同一个地方)。我已经看到它在路由器、视图的初始化或渲染函数中完成,或者只是在根级文档就绪函数中完成。( $(function ()
) 。我可以想象这些工作中的任何一个,但是有没有正确的方法来做到这一点?
Second, I am starting with some HTML markup/wireframe, and converting html portions to js templates corresponding to backbone views. Rather than let the view render an unattached element and providing an anchor point in the html to stick it in, I feel like its more natural, when there is only going to be one element for a view and it won't be going away, to use an existing, emptied wrapper element (often a div
or span
) as the el
itself. That way I don't have to worry about finding the place in the document to insert my unattached el, which would potentially end up looking like this (note the extra layering):
其次,我从一些 HTML 标记/线框开始,并将 html 部分转换为与主干视图相对应的 js 模板。与其让视图呈现一个未附加的元素并在 html 中提供一个锚点来粘贴它,我觉得它更自然,当视图只有一个元素并且它不会消失时,使用现有的、清空的包装元素(通常是 adiv
或span
)作为它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>
So part of my second question is, for a basically static view, is there anything wrong with using an existing element from the page's HTML directly as my view's el
? This way I know its already in the DOM, in the right place, and that calling render will immediately render the view on the page. I would acheive this by passing the already exixting element to my view's constsructor as 'el'. That way, it seems to me, i don't have to worry about sticking it into the DOM (making question 1 sort of moot), and calling render will immediately update the DOM. E.g.
所以我的第二个问题的一部分是,对于一个基本静态的视图,直接使用页面 HTML 中的现有元素作为我的视图有什么问题el
吗?这样我就知道它已经在 DOM 中,在正确的位置,并且调用 render 将立即在页面上呈现视图。我会通过将已经存在的元素作为“el”传递给我的视图的构造函数来实现这一点。这样,在我看来,我不必担心将其粘贴到 DOM 中(使问题 1 没有实际意义),并且调用 render 将立即更新 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>
Is this an OK way to do it for static views on the page? i.e., there is only one of these views, and it will not go away in any circumstance. Or is there a better way? I realize that there may be different ways to do things (i.e., in a router, in a parent view, on page load, etc.) based on how I am using a view, but right now I am looking at the initial page load use case.
对于页面上的静态视图,这是一种可行的方法吗?即,这些视图只有一种,并且在任何情况下都不会消失。或者,还有更好的方法?我意识到根据我使用视图的方式可能有不同的做事方式(即,在路由器中,在父视图中,页面加载等),但现在我正在查看初始页面加载用例。
Thanks
谢谢
采纳答案by jcreamer898
There's absolutely nothing wrong with the idea of attaching a view to an existing DOM node.
将视图附加到现有 DOM 节点的想法绝对没有错。
You can even just put the el as a property on your view.
您甚至可以将 el 作为属性放在您的视图中。
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();
});
What I recommend is, do what works... The beauty of Backbone is that it is flexible and will meet your needs.
我的建议是,做有效的事…… Backbone 的美妙之处在于它很灵活,可以满足您的需求。
As far as common patterns are concerned, generally I find myself having a main view to keep track of over views, then maybe a list view and individual item views.
就常见模式而言,通常我发现自己有一个主视图来跟踪过度视图,然后可能是列表视图和单个项目视图。
Another common pattern as far as initialization is concerned is to have some sort of App object to manage stuff...
就初始化而言,另一种常见模式是使用某种 App 对象来管理内容......
var App = (function ($, Backbone, global) {
var init = function () {
global.myView = new myView();
};
return {
init: init
};
}(jQuery, Backbone, window));
$(function () {
App.init();
});
Like I said before though, there's really no WRONG way of doing things, just do what works. :)
就像我之前说的,做事真的没有错误的方式,只要做有效的事。:)
Feel free to hit me up on twitter @jcreamer898 if you need any more help, also check out @derickbailey, he's kind of a BB guru.
如果您需要更多帮助,请随时在 twitter @jcreamer898 上联系我,也可以查看 @derickbailey,他是一位 BB 大师。
Have fun!
玩得开心!
回答by andho
You can also send an HTML DOM Element object into the view as the 'el' property of the options.
您还可以将 HTML DOM 元素对象作为选项的 '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')
});
});
回答by Oleksandr Knyga
Use delegate events method:
使用委托事件方法:
initialize: function() {
this.delegateEvents();
}
To understand why: http://backbonejs.org/docs/backbone.html#section-138near "Set callbacks, where"
要了解原因:http://backbonejs.org/docs/backbone.html#section-138靠近“设置回调,在哪里”
回答by pixelearth
Looks also like these days you can youse setElement.
看起来这些天你也可以使用setElement。