我正在使用Backbone.js(使用Underscore模板),Express和Node.js构建应用程序。
我用这个非常简单的例子来说明问题(见下面的代码),应用程序包含从服务器检索到的“标题”列表。
我使用下划线模板来呈现HTML。在呈现HTML之后,我想执行一些jQuery代码,例如在控制台中打印每个“标题”的position()。 问题是在模板将元素插入DOM之前调用jQuery代码,因此jQuery无法找到元素。
我错过了什么? 在将DOM插入DOM后,是否有办法获取事件?
这里是代码:
<div class="container">
<div id="tracks">
</div>
</div>
<!-- Template -->
<script id="trackTemplate" type="text/template">
<ul id="<%= id2 %>" style="height:150px">
<li><%= title %></li>
</ul>
<%
// So it looks like this code gets code before the template's HTML is in the DOM.
console.log($("#"+id2).position());
%>
</script>
<script src="js/lib/jquery-1.10.2.min.js"></script>
<script src="js/lib/underscore-min.js"></script>
<script src="js/lib/backbone-min.js"></script>
<script>
var app = app || {};
// Model
app.Track = Backbone.Model.extend({
defaults: {
id2: '',
title: 'Track',
},
});
// Collection
app.Library = Backbone.Collection.extend({
model: app.Track,
url: '/api/tracks'
});
// Track view
app.TrackView = Backbone.View.extend({
tagName: 'div',
className: 'trackContainer',
template: _.template( $( '#trackTemplate' ).html() ),
initialize:function(){
this.model.on('change', this.render, this);
},
render: function() {
this.$el.html( this.template( this.model.toJSON() ) );
return this;
},
});
// Collection View
var numberOfTracks = 0;
app.LibraryView = Backbone.View.extend({
el: '#tracks',
initialize: function( initialTracks ) {
this.collection = new app.Library( initialTracks );
this.collection.fetch();
this.listenTo( this.collection, 'add', this.renderTrack);
},
// render library by rendering each track in its collection
render: function() {
this.collection.each(function( item ) {
this.renderTrack( item );
numberOfTracks++;
}, this );
},
// render a track by creating a trackView and appending the
// element it renders to the library's element
renderTrack: function( item ) {
var trackView = new app.TrackView({
model: item
});
this.$el.append( trackView.render().el );
},
});
// Initialise app
var libraryView = new app.LibraryView();
</script>
由于
答案 0 :(得分:1)
为了覆盖这里的某些内容,一旦将某些内容插入DOM中,就不会触发事件。我实际上并不主张通过将代码放入模板中来试图解决这个问题。而是看看你的视图呈现方式。
如果你想把一些代码扔进一个预先存在的占位符,你可以看看做这样的事情:
[view here].setElement(this.$([selector here])).render();
对此有一个很好的解释:
http://ianstormtaylor.com/rendering-views-in-backbonejs-isnt-always-simple/
如果您不需要任何重量级的子视图管理,这是一种安排子视图的简洁方法。你应该在那之后能够使用jquery做一些事情,正如你通常在视图中使用这个。$ el和this。$。在视图中正确确定元素的范围。
答案 1 :(得分:0)
console.log
电话的正确位置将在render
方法的最后或renderTrack
中append
之后。
Backbone还可以轻松创建自己的活动并通过Backbone.Events注册。你可以在我在前一段中提到的地方之一发起自己的事件。
有一个不推荐使用的事件系列用于跟踪名为Mutation events的DOM中的更改 - 但它们已弃用且浏览器支持不太可靠。替换是MutationObserver,在DOM4 spec中定义,浏览器支持尚不存在(IE仅支持11)但是对于测试它可能有用。
另一种方法是将您的代码放在setTimeout
中 - 这样,您console.log
运行时肯定会插入DOM节点。