我正在编写我的第一个Backbone.js应用程序,我在找出最好的编程方法时遇到了一些困难。我有两个主要意见:
但是2号有很多不同的“模块”,比如我可以编辑“新闻”部分,或者“关于”部分等等.所有这些模块都在导航栏中。
当我显示视图#1(所有模型的索引)时,导航栏是隐藏的。它在视图2(一个特定的模型)中是可见的,以便在不同模块之间导航。
我有这样的路线:
routes: {
'', 'index',
'communities': 'index',
'communities/:id': 'main',
'communities/:id/news', 'news',
'communities/:id/about', 'about'
},所以我的问题是,当调用'news‘或'about’操作时,是否在每个方法中添加一个导航栏?这不是多余吗?我将有8-10个不同的模块,添加导航栏每次似乎非常重复。有更好的办法吗?我唯一想要隐藏导航条的时候是显示索引时。
发布于 2012-07-03 14:04:42
当我创建了我的第一个有点复杂的骨干应用程序时,我遇到了同样的问题。除了您对冗余代码的关注之外,我还关注绑定到导航栏的事件,这些事件可能不会随着导航栏的更改而解除绑定。为了解决这个问题,我最终创建了一个视图层次结构,其中一个管理器视图管理导航栏,并为我想要显示的每种类型的导航菜单单独显示视图,这些视图将被传递给manager视图以呈现给页面。
下面是我实现的一个例子。
在开始之前,这里是我添加到主干的close原型中的一个View函数,它解除事件绑定并删除视图
Backbone.View.prototype.close = function() {
if(this.beforeClose) { this.beforeClose(); }
this.remove();
this.unbind();
}首先,这里是我的管理器视图。它的render函数关闭当前显示的菜单,并将其替换为传递给它的菜单为view。虽然有点多余,但我创建了一个显式的empty函数,以使我的路由器代码更容易理解。
var App.Views.SubNavBar = Backbone.View.extend({
currentView: null,
el: '#subnav-wrap',
render: function(view) {
if(this.currentView) { this.currentView.close(); }
this.currentView = view;
this.$el.html(view.el);
},
empty: function() {
if(this.currentView) { this.currentView.close(); }
this.currentView = null;
}
});第二,下面是我所有特定导航菜单视图扩展的基本视图。由于它们都将具有相同的tagName、className、id、initialize和render函数,这使得重复次数减少到最低限度。
var App.Views.SubNavBase = Backbone.View.extend({
tagName: 'ul',
className: 'nav nav-pills',
id: 'subnav',
template: _.template($('#tmpl-subnav').html(),
initialize: function() {
if(this.setLinks) { this.setLinks(); }
this.render();
},
render: function() {
this.$el.html(this.template({links:this.links}));
return this;
}
});下面是一个特定导航菜单的视图示例。您可以看到,我所需要做的就是定义我想要显示在菜单中的链接。当我实例化这个视图时,SubNavBase的函数将处理使用所需的HTML填充视图。请注意,我也有一些事件附加到这个视图。
var App.Views.Projects.DisplayNav = App.Views.SubNavBase.extend({
setLinks: function() {
this.links = {
'Edit Project': {
icon: 'edit',
class: 'menu-edit',
href: '#projects/'+this.model.get('id')+'/edit'
},
'Add Group': {
icon: 'plus',
class: 'menu-add-group',
href: '#projects/'+this.model.get('id')+'/groups/new'
},
'Delete Project': {
icon: 'trash',
class: 'menu-delete',
href: '#'
}
}
},
events: {
'click a.menu-delete' : 'delete'
},
delete: function(e) {
e.preventDefault();
// here goes my code to delete a project model
}
});下面是我使用的underscore.js模板,用于将上面的links对象转换为一个<li>元素列表。注意,我使用<@而不是<%作为模板,因为这是一个rails应用程序,rails已经使用了<%
<script type="text/template" id="tmpl-subnav">
<@ _.each(links,function(link, title) { @>
<li>
<a href="<@= link.href @>" class="<@= link.class @>">
<i class="icon-<@= link.icon @>"></i>
<@= link.title @>
</a>
</li>
<@ }); @>
</script>最后,为了把它们放在一起,下面是一个创建和呈现nav菜单的示例Router函数。发生的步骤如下:
App.Views.Projects.DisplayNav得到一个模型,并使用相应的underscore.js模板填充其this.el。App.SubNavBar使用新的菜单视图调用它的render函数App.SubNavBar检查导航栏中当前是否有另一个菜单;如果是,则调用视图的close()函数App.SubNavBar最后将传递的视图的HTML附加到自身,维护对视图的引用,以供以后使用我只包含了路由器代码的相关部分
var App.Routers.Projects = Backbone.Router.extend({
routes: {
'projects/:id' : 'display'
},
display: function(id) {
var p = projects.get(id);
var subnav = new App.Views.Projects.DisplayNav({model:p})
App.SubNavManager.render(subnav); // App.SubNavManager is an instance of App.Views.SubNavBar
}
});所有这些的好处是,我现在可以将事件附加到特定于菜单的视图中,如果用户导航到不同的内容和菜单更改,manager视图将负责解除绑定。
当然,您还可以使用许多其他模式来处理导航菜单,但希望这将对您的路径有所帮助。
发布于 2012-07-03 13:19:58
试试这个:
routes: {
'', 'index',
'communities': 'index',
'communities/:id': 'main',
'communities/:id/:section': 'openSection'
},
openSection : function(id, section){
if( section ){
this.addNavigationBar();
}
switch( section ){
case 'news' :
this.news();
break;
case 'about' :
this.about();
break;
default:
this.main();
}
}如果您的url包含一个部分,您将添加导航栏,然后按照您的情况调用您的普通方法。
https://stackoverflow.com/questions/11308138
复制相似问题