在尚未添加到 DOM 的视图上使用骨干事件 - 渲染问题
短篇故事...我有嵌套视图,但只有顶级视图可以处理事件,因为我只将“el”属性传递给顶级视图。
长话短说...
我正在创建一个时间线项目,使用主干作为 JS/GUI 客户端应用程序。我用于渲染水平时间线的模板如下:
<script type="text/template" id="yearGroups">
<![CDATA[
<% _.each(columns, function(item,i) { %>
<div class="yearGroup">
<h2><%= item.yearLabel %></h2>
<div class="years">
<% _.each(item.years, function(year, b) { %>
<div class="year">
<% _.each(year.searchGroups, function(sg, sg_index) { %>
<%= jQuery(sg.viewEl).html() %>
<% }); %>
</div>
<% }); %>
</div>
</div>
<% }); %>
]]>
</script>
每年可以有多个搜索,因此可以有多个 searchGroups
。 每个 searchGroup
都包含 eventBlocks
作为每个搜索结果的包装器。
下面是创建 SearchGroupViews
的循环中的代码片段(它创建了此处未显示的 eventBlocks
)。
var events = eventCollection.getEventsInYear(year);
if(events.length > 0) {
var sgv = new SearchGroupView({results: events, searchID: 'search1'});
this.searchGroups.push(sgv);
renderedResults.push({viewEl:sgv.render().el});
}
然后,renderedResults
最终传递到模板,如下所示:
$(this.el).html(this.template({columns:col}));
... 并在每个 .year 下渲染,使用:
jQuery(sg.viewEl).html().
所有这些意味着我的嵌套视图不会收到任何事件,因为它们没有使用 'el' 属性传入的容器 div。它们没有容器,因为它是在构建所有视图之后渲染的(请参阅第一个代码块)。
我当前的解决方案是使用全局 eventManager
,它可以用作事件处理程序,以便在顶级视图调用 eventManger.trigger(..)
时通知视图。这并不理想。
必须有一个解决方案允许我的嵌套视图在渲染事件后拾取事件?或者我是否需要预渲染顶级视图模板并指定 el 属性,例如 {el: '.year.yearID-1984'}
和 {el: '.searchGroup.groupID- 6'}
?
理想情况下,我可以渲染 sg.viewEl
而不仅仅是该对象的 html 输出,然后视图会自我意识到它在哪里。 ...但我知道那是不可能:(
希望这是清楚的。
Short story... I have nested views but only the top level view can work with events because I am only passing in the 'el' property to the top level view.
Long story...
I am creating a timeline project using backbone as JS/GUI client side app. My template for rendering the horizontal timeline is like this:
<script type="text/template" id="yearGroups">
<![CDATA[
<% _.each(columns, function(item,i) { %>
<div class="yearGroup">
<h2><%= item.yearLabel %></h2>
<div class="years">
<% _.each(item.years, function(year, b) { %>
<div class="year">
<% _.each(year.searchGroups, function(sg, sg_index) { %>
<%= jQuery(sg.viewEl).html() %>
<% }); %>
</div>
<% }); %>
</div>
</div>
<% }); %>
]]>
</script>
There can be multiple searches and therefore multiple searchGroups
per year.
Each searchGroup
contains eventBlocks
as a wrapper for each search result.
Below is a code snippet from the loop which creates the SearchGroupViews
(which creates the eventBlocks
not shown here).
var events = eventCollection.getEventsInYear(year);
if(events.length > 0) {
var sgv = new SearchGroupView({results: events, searchID: 'search1'});
this.searchGroups.push(sgv);
renderedResults.push({viewEl:sgv.render().el});
}
renderedResults
is then eventually passed through to the template like this:
$(this.el).html(this.template({columns:col}));
... and rendered under each .year using:
jQuery(sg.viewEl).html().
All of this means that my nested views don't receive any events because they don't have a container div passed in using the 'el' attribute. They don't have a container because that's rendered after all the views are built (see first code block).
My current solution is to use a global eventManager
that can be used as an event handler to notify views when the top level view calls an eventManger.trigger(..)
. This is not ideal.
There must be a solution that allows my nested views to pick up on the events after they have been rendered? Or do I need to pre-render the top level view template and specify el attributes like {el: '.year.yearID-1984'}
and {el: '.searchGroup.groupID-6'}
?
Ideally I could render sg.viewEl
and not simply the html output from that object and the view would then be self aware of where it is. ... but I know that's not possible :(
Hope this is clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我实现了一个接近我的问题中描述的解决方案...
渲染顶级视图后,然后调用:
然后在每个视图初始化函数中捕获此事件...
...以便视图可以更新埃尔财产。这一切都依赖于用于查找 el 的唯一类名(例如,class="nid-1234")。
我猜这与在 init 上设置 view el 属性相同,因为我知道它所基于的 id。这假设主干使用 .live(..) 来查找 el: ".nid-1234" DOM 对象。
I implemented an ok solution close to what was described in my question...
After rendering the top level view, I then call:
This event is then captured in each view init function....
...so that the view can update the el property. This all relies on a unique class name being used to find the el (eg, class="nid-1234").
I'm guessing this would then be the same as setting the view el property on init given that I know the id it's based on. This assumes that backbone uses .live(..) for finding the el: ".nid-1234" DOM obj.