我正在Backbone中构建一个网站,其网站结构类似于Youtube,因为当您使用页面链接更改页面时,只会重新加载一部分DOM(即非导航组件)整个文件。
因此,当用户使用我网站上的链接访问子页面时,Backbone将发出一个AJAX调用并接收子页面的HTML,如下所示:
<section id="SubpageView">...</section>
<script>
// Defines the view that controls #SubpageView.
if(typeof SubpageView !== 'undefined') {
// If this is the first time the page is loaded, create class.
var SubpageView = Backbone.Model.extend({
el: '#SubpageView',
...
});
}
MainView.currentSubpage = new SubpageView();
</script>
多次调用SubpageView()有任何缺点(即僵尸视图,内存泄漏等)吗?在我看来,使用 el 而不是 tagName 定义一个View元素是用于仅使用一次的元素。
注意:我知道单页网页应用程序通常将所有模板都放在持久性DOM中,所有HTML都是使用客户端模板处理的。但是因为我设计的网站在没有pushState()的情况下降级为传统的服务器端渲染,或者当Javascript被禁用时,我不想将我的所有模板都烘焙到持久性DOM中。
答案 0 :(得分:2)
这是一个很好的问题 - 我认为很多人都忽略了这个问题而且会引发问题。 &#34; Zombie Views&#34;是一个伟大的描述。我说你是对的他们可能会导致问题:
如果您使用Backbone的事件哈希,那么最后一点尤其重要,例如:
events: {
'click .someButton': 'someMethod',
// ...
},
由于您正在重用el
选择器(我认为您应该这样做),所有僵尸视图的事件将保持活动状态,并在不需要时触发视图的功能。这可能意味着重复行为或其他完全意外的结果。
至于解决方案,我认为你有两个选择:一个是在更新之前销毁你的旧视图实例。默认的remove
方法实际上删除了您不想要的el
... undelegateEvents
可能有所帮助。 Backbone并没有真正干净的方式去做所需的事情,所以你最终会自己编写一些代码。
我认为更好的选择是使用新数据(collection
,model
,其他实例数据或其他任何适当的数据重复使用现有的视图实例。
当您更改页面的子视图时,您可能会传入一些变量,比如获取的html:
$.get('/templates/someView.html', function(html) {
Mainview.currentSubpage = new SubpageView(html);
});
......或类似的东西。相反,我建议使用方法来编写更新现有实例,例如:
$.get('/templates/someView.html', function(html) {
Mainview.currentSubpage.resetPage(html);
});
您可以将resetPage
方法写入SubpageView
,以满足您的需求。这当然不仅仅适用于html传递,我只是以此为例。