0xS*_*ina 1 javascript backbone.js
我正在编写我的第一个Backbone.js应用程序,我在查找编程它的最佳方法时遇到了一些麻烦.我有2个主要观点:
但是#2有许多不同的"模块",比如我可以编辑"新闻"部分或"关于"部分等...所有这些模块都在导航栏中.
当我显示视图#1(所有模型的索引)时,该导航栏被隐藏.它在视图#2(特定模型)中可见,以便在不同模块之间导航.
我有这样的路线设置:
routes: {
'', 'index',
'communities': 'index',
'communities/:id': 'main',
'communities/:id/news', 'news',
'communities/:id/about', 'about'
},
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,当'新闻'或'关于'动作被调用时,我是否在每个方法中添加导航栏?这不是多余的吗?我将有8-10个不同的模块,每次添加导航栏似乎非常重复.有没有更好的办法?我希望隐藏导航栏的唯一时间是显示索引.
当我创建我的第一个有点复杂的Backbone应用程序时,我遇到了同样的问题.除了您对冗余代码的关注之外,我还担心绑定到导航栏的事件可能会在导航栏更改时无法解除绑定.为了解决这个问题,我开始创建一个视图层次结构,一个管理器视图管理整个导航栏,并为我想要显示的每种导航菜单分别显示视图,这些视图将传递给管理器视图以呈现给页.
这是我实施的一个例子.
在我们开始之前,这是close我添加到Backbone的View原型中的一个函数,它取消绑定事件并删除视图
Backbone.View.prototype.close = function() {
if(this.beforeClose) { this.beforeClose(); }
this.remove();
this.unbind();
}
Run Code Online (Sandbox Code Playgroud)
首先,这是我的经理视图.它的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;
}
});
Run Code Online (Sandbox Code Playgroud)
其次,这是我所有特定导航菜单视图扩展的基本视图.因为他们都具有相同的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;
}
});
Run Code Online (Sandbox Code Playgroud)
以下是特定导航菜单的视图示例.您可以看到我需要做的就是定义我想要在菜单中显示的链接.当我实例化这个视图时,函数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
}
});
Run Code Online (Sandbox Code Playgroud)
现在,这是我用来将上面的链接对象转换为<li>元素列表的underscore.js模板.请注意,我使用<@而不是<%我的模板,因为这是一个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>
Run Code Online (Sandbox Code Playgroud)
最后,将它们放在一起,这是一个Router创建和渲染导航菜单的示例函数.发生的步骤如下:
App.Views.Projects.DisplayNav传递一个模型,并this.el使用相应的HTML 填充它,由underscore.js模板确定App.SubNavBarrender使用新菜单视图调用其功能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
}
});
Run Code Online (Sandbox Code Playgroud)
所有这一切的好处是我现在可以将事件附加到我的菜单特定视图,如果用户导航到不同的内容并且菜单更改,则管理器视图将负责解除它们的绑定.
当然,您可以使用许多其他模式来处理导航菜单,但希望这可以帮助您走上正轨.
| 归档时间: |
|
| 查看次数: |
2456 次 |
| 最近记录: |