我现在已经看了一会儿,但却找不到任何可能导致这种情况的原因。
我的代码:
var faqView = Backbone.View.extend({
tagName: 'div',
id: 'faq-list',
initialize: function() {
var view = this;
this.collection = new faqCollection();
this.collection.fetch({
success: function(collection, response) {
collection.each(function(faq){
view.$el.append(_.template($('script#faq_item').html(),{faq: faq.attributes}));
});
},
error: function(collection, response) {
view.$el.html("<p>Unable to get the FAQ items.<br>Please try again later.</p>");
}
});
},
render: function() {
this.$el.appendTo('div#container');
return this;
},
events: {
'click h3': 'toggleAnswer'
},
toggleAnswer: function(event) {
console.log(this);
console.log(event);
}
});
var router = Backbone.Router.extend({
routes: {
"faq": "faq",
"*other": "defaultRoute"
},
faqView: {},
initialize: function() {
this.faqView = new faqView();
},
defaultRoute: function() {
this.resetPage();
},
faq: function() {
this.resetPage();
$('body').addClass('page-faq');
this.faqView.render();
},
resetPage: function() {
$('body').removeClass('page-faq');
this.faqView.remove();
}
});
以上代码包含在<body>
的最后一项中。 HTML如下。
<body>
<div id="container">
</div>
<script type="text/template" id="faq_item">
<h3 class="contracted"><span>{{faq.question}}</span></h3>
<p style="display: none;">{{faq.answer}}</p>
</script>
<script type="text/javascript" src="./js/models.js"></script>
<script type="text/javascript" src="./js/views.js"></script>
<script type="text/javascript" src="./js/collection.js"></script>
<script type="text/javascript" src="./js/router.js"></script>
<script type="text/javascript">
//<![CDATA[
$(function() {
var app = new router;
Backbone.history.start();
});
//]]>
</script>
</body>
所有必需的元素都存在(据我所知)并且我没有手动设置View的el
属性。我很遗憾,为什么在点击<h3>
时事件没有绑定/触发。
编辑如果我不使用路由器并自行创建视图,则不会抛出任何错误并且功能正常工作。 e.g。
var app = new faqView();
app.render();
答案 0 :(得分:3)
您的问题出在路由器中。就在这里:
resetPage: function() {
$('body').removeClass('page-faq');
this.faqView.remove();
}
默认情况下,{p> View#remove
在el
视图上只有jQuery's remove
而且:
[...]方法从DOM中获取元素。 [...]删除了与元素关联的所有绑定事件和jQuery数据
因此,一旦this.faqView.remove()
,驱动视图事件的delegate
处理程序就会消失。
通常的方法是根据需要创建和销毁视图,而不是创建视图并将其缓存以供日后使用。您的路由器看起来应该更像这样:
var router = Backbone.Router.extend({
routes: {
"faq": "faq",
"*other": "defaultRoute"
},
defaultRoute: function() {
this.resetPage();
},
faq: function() {
this.resetPage();
$('body').addClass('page-faq');
this.view = new faqView();
this.view.render();
},
resetPage: function() {
$('body').removeClass('page-faq');
if(this.view)
this.view.remove();
}
});
演示:http://jsfiddle.net/ambiguous/aDtDT/
您可以尝试在remove
中的被覆盖的faqView
方法中使用detach
进行操作,但实际上并不需要一直有faqView
个实例:在需要时创建它,然后在不需要时删除它。