在我的应用程序的许多地方,都会发生以下情况:
我尝试了以下两种实现模式:
>
路由器处理获取
获取视图句柄
我不喜欢#1,因为路由器变成了一个巨大的模型/集合获取逻辑球,似乎有太多的责任。#2似乎是更好的责任分配(路由器只是决定显示哪个视图,视图找出它需要获取的数据),但是它确实使视图渲染变得有点棘手,因为它现在是有状态的。
StackOverflow社区是怎么想的?1,2,还是别的?
这篇文章很老了,但我们今天早些时候已经看过了,所以万一有人看到它:
对我来说,我确实看到了两个不同的问题:
我们的一些处理方法与一些个人偏好混合在一起:
我喜欢尤里的要点,还有几个警告(缩进的子弹):
渲染器的主要原因是处理与该部分相关的事情,比如清理现有视图以避免重影视图,在渲染时滚动到顶部(我们的主内容渲染器会这样做),或者在这种情况下显示旋转器。
一个类似于伪代码的例子,说明了这可能是什么样子:
路由器:
routes: {
"profile": "showProfile"
},
showProfile: function() {
return new ProfileController().showProfile();
}
配置文件控制器:
showProfile: function() {
//simple case
var model = new Model();
var deferredView = model.fetch.then(function() {
return new View(model);
};
MainContentRenderer.renderDeferred(deferredView);
}
主内容渲染器:
var currentView;
renderDeferred: function(deferredView) {
showSpinner();
deferredView.then(function(view) {
this.closeSpinner();
this.closeCurrentView();
this.render(view);
}
},
render: function(view) {
currentView = view;
$('#main-content').html(view.render().el);
}
closeCurrentView: function() {
if (currentView and currentView.close()) {
currentView.close();
}
}
引入控制器还具有可测试性的额外好处。例如,我们有复杂的规则来执行围绕URL管理的搜索,在结果视图和新搜索视图之间进行选择,以及在缓存的“最后”搜索结果和执行新搜索之间进行选择。我们对控制器进行了Jasmine测试,以验证所有的流逻辑都是正确的。它还提供了一个孤立的地方来管理这些规则。
我倾向于将第二个选项用于三个视图:容器视图、加载视图和内容视图。也就是说,容器由路由器实例化,在每次渲染期间,它查看手头上要显示的内容(有时由路由器提供,有时由自身提供),并决定实例化哪个视图。一个过于简单、人为的例子:
ContainerView = Backbone.View.extend({
initialize: function (options) {
options.data.bind("reset", this.render, this);
},
render: function () {
var view;
// If the loading view is only shown once, e.g., splashing, then isReady()
// may be better here.
if (this.options.data.isLoading()) {
view = LoadingView;
} else {
view = DataView;
}
this.$("div.content").html(new view().render().el);
}
});
我喜欢这种方法,因为:
澄清:在这种情况下,视图的目的是理解如何最好地向用户显示要显示的内容。在这种情况下,仍在加载的数据最好用加载视图显示,而就绪数据最好用数据视图显示。大多数真实视图实际上是用更多的视图组成它们的显示,例如,根据用户授权不同的操作容器。