backbone router view.router可以一个锚点对应两个链接吗

当前访客身份:游客 [
Backbone.js 的技巧和模式
英文原文:
HTTP Status Code 200 Trigger Error
If the endpoint that your model or collection is hitting returns invalid JSON, then your model or collection will trigger an “error” event, even if the endpoint returns a 200 HTTP status code. This issue mostly comes up when developing locally against mock JSON data. So, a good rule of thumb is to throw any mock JSON files you’re developing through a . Or get a plugin for your IDE that will catch any ill-formatted JSON.
HTTP状态代码200所触发的错误
如果你的浏览器端模型或者集合收到了无效的JSON,尽管HTTP的状态代码是200,但浏览器端依然会触发一个“错误”事件。这种事件常发生于本地模拟JSON数据造成的。那么,一个好的方法就是读取经过
验证了的模拟JSON数据文件。或者从你的IDE获得相应的
插件来及时获取格式错误的JSON信息。
Create A Generic Error Display
This one could save you time and create a uniform pattern for handling and visualizing error messages, which will improve your user’s overall experience. In any Backbone.js app that I develop, I create a generic view that handles alerts:
var AlertView = Backbone.View.extend({
set: function(typeOfError, message) {
var alert = $(‘.in-page-alert’).length ? $(‘.in-page-alert’): $(‘.body-alert’);
.removeClass(‘error success warning’)
.addClass(typeOfError)
.html(message)
.delay(5000)
.fadeOut();
The view above first looks to see whether there is a view-specificin-page-alertdiv, which you would declare inside of your view’s markup. If there is no view-specific div, then it falls back to a genericbody-alertdiv, which you would declare somewhere in the layout. This enables you to deliver a consistent error message to your users and provides a useful fallback in case you forget to specify a view-specificin-page-alertdiv. The pattern above streamlines how you handle error messages in your views, as follows:
var alert = new AlertView();
this.model.on('error', function(model, error) {
alert.set('TYPE-OF-ERROR', error);
创建一个一般性错误显示模式
创建一个常见错误显示代码可以节省你的时间以及创建一个统一的模式来处理、可视化错误信息,而且它可以增加开发者的经验。我之前开发的每一个Backbone.js应用中我都会创建一个可以处理alert的视图:
var AlertView = Backbone.View.extend({
set: function(typeOfError, message) {
var alert = $(‘.in-page-alert’).length ? $(‘.in-page-alert’): $(‘.body-alert’);
.removeClass(‘error success warning’)
.addClass(typeOfError)
.html(message)
.delay(5000)
.fadeOut();
上面的代码首先会检查是否已在视图代码中创建了指定视图in-page-alert div。如果没有,则接着查看一般性的在其它地方声明的body-alert div。这样可以让你发送具有一致性的错误信息以及当你忘记指定一个in-page-alert div时提供有用且可靠的信息。如下面的模式简化了让你怎样在你的试图中处理错误信息:
var alert = new AlertView();
this.model.on('error', function(model, error) {
alert.set('TYPE-OF-ERROR', error);
Update Single-Page App Document Titles
This is more of a usability concern than anything. If you’re developing a single-page application, remember to update the document title of each page! I’ve written a simple Backbone.js plugin, , that does this in a simple and elegant format by extending the Backbone.js router. It allows you to specify a title’s object literal, whose keys map to route function names and whose values are page titles.
Backbone.Router = Backbone.Router.extend({
initialize: function(options){
var that =
this.on('route', function(router, route, params) {
if(that.titles) {
if(that.titles[router]) document.title = that.titles[router];
else if(that.titles.default) document.title = that.titles.
else throw 'Backbone.js Router Title Helper: No title found for route:' + router + ' and no default route specified.';
单页面应用中更新浏览器页面标题
这是一个比任何东西都重要的可用性问题。如果你正在开发一个单页面应用程序,谨记更新每个页面的标题。我写过一个的插件()来扩展 backbone.js router 的功能。它通过一个 Map 对象来控制路由,键来代表路由函数的名字,值则映射到页面的标题。
Backbone.Router = Backbone.Router.extend({
initialize: function(options){
var that =
this.on('route', function(router, route, params) {
if(that.titles) {
if(that.titles[router]) document.title = that.titles[router];
else if(that.titles.default) document.title = that.titles.
else throw 'Backbone.js Router Title Helper: No title found for route:' + router + ' and no default route specified.';
Cache Objects In Single-Page Applications
While we are on the topic of single-page applications, another pattern you could follow is to cache objects that will be reused! This case is fairly straightforward and simple:
// Inside a router
initialize: function() {
this.cached = {
view: undefined,
model: undefined
index: function(parameter) {
this.cached.model = this.cached.model || new Model({
parameter: parameter
this.cached.view = this.cached.view || new View({
model: this.cached.model
This pattern will give your application a small bump in speed because you won’t have to reinitialize your Backbone.js objects. However, it could cause your application’s memory footprint
so, I’ll typically only cache objects that are commonly used throughout an application. If you’ve developed Backbone.js apps in the past, then you’re likely asking yourself,
“What if I want to refetch data?” You can refetch data each time the route is triggered:
// Inside a router
initialize: function() {
this.cached = {
view: undefined,
model: undefined
index: function(parameter) {
this.cached.model = this.cached.model || new Model({
parameter: parameter
this.cached.view = this.cached.view || new View({
model: this.cached.model
this.cached.model.fetch();
This pattern will work when your application must retrieve the latest data from the endpoint (for example, an inbox). However, if the data that you’re fetching is dependent on the state of the application (assuming that the state is maintained through your URL and parameters), then you would be refetching data even if the application’s state hasn’t changed since the user was last on the page. A better solution would be to refetch data only when the state of the application (parameter) has changed:
// Inside a router
initialize: function() {
this.cached = {
view: undefined,
model: undefined
index: function(parameter) {
this.cached.model = this.cached.model || new Model({
parameter:parameter
this.cached.model.set('parameter', parameter);
this.cached.view = this.cached.view || new View({
model: this.cached.model
// Inside of the model
initialize: function() {
this.on(&change:parameter&, this.fetchData, this);
单页面应用中的缓存对象
当我们谈论单页面应用时,另一个叫缓存对象模式你将会经常用到!下面的例子直截了当而且简单:
// Inside a router
initialize: function() {
this.cached = {
view: undefined,
model: undefined
index: function(parameter) {
this.cached.model = this.cached.model || new Model({
parameter: parameter
this.cached.view = this.cached.view || new View({
model: this.cached.model
} 这个模式可以加速你得应用,因为你不用重复初始化你得Backbone.js对象。然而,它会过多的消耗内存;所以,缓存对象就要在整个应用中使用。如果以前你用过Backbone.js开发过应用,也许你会问你自己,“
我要重取数据该怎么做?”你可以每次在如下路径中触发后重取数据:
// Inside a router
initialize: function() {
this.cached = {
view: undefined,
model: undefined
index: function(parameter) {
this.cached.model = this.cached.model || new Model({
parameter: parameter
this.cached.view = this.cached.view || new View({
model: this.cached.model
this.cached.model.fetch();
} 当你的应用从端点(如,一个收件箱)必须检索最新数据时上面的模式就可以工作。当然,如果你要拿的数据时凭借应用的某个状态(假设这个状态是通过URL和参数来决定的),甚至是在用户上一个页面应用的状态没有改变,
你可以重取数据。一个好的解决方案去重拿数据时当应用(参数)发生变化时:
// Inside a router
initialize: function() {
this.cached = {
view: undefined,
model: undefined
index: function(parameter) {
this.cached.model = this.cached.model || new Model({
parameter:parameter
this.cached.model.set('parameter', parameter);
this.cached.view = this.cached.view || new View({
model: this.cached.model
// Inside of the model
initialize: function() {
this.on(&change:parameter&, this.fetchData, this);
JSDoc Functions And Backbone.js Classes
I’m a huge fan of documentation and . I JSDoc all Backbone classes and functions in the following format:
var Thing = Backbone.View.extend(/** @lends Thing.prototype */{
/** @class Thing
* @author Phillip Whisenhunt
* @augments Backbone.View
* @contructs Thing object */
initialize() {},
/** Gets data by ID from the thing. If the thing doesn't have data based on the ID, an empty string is returned.
* @param {String} id The id of get data for.
* @return {String} The data. */
getDataById: function(id) {}
If you document your Backbone classes in the format above, then you can generate beautiful documentation that contains all of your classes and functions with parameters, return types and descriptions. Be sure to keep theinitializefunction as the first function declared, which helps when generating JSDoc. If you’d like to see an example of a project that uses JSDoc, check out the . There is also a
plugin, , to generate documentation as part of your build process.
JSDoc函数和Backbone.js类
我是文档注释和的超级粉丝。我用JSDoc对所有的Backbone类添加了文档注释:
var Thing = Backbone.View.extend(/** @lends Thing.prototype */{
/** @class Thing
* @author Phillip Whisenhunt
* @augments Backbone.View
* @contructs Thing object */
initialize() {},
/** Gets data by ID from the thing. If the thing doesn't have data based on the ID, an empty string is returned.
* @param {String} id The id of get data for.
* @return {String} The data. */
getDataById: function(id) {}
}); 如果你对Backbone类进行如上添加文档注释,这样你可以给所有类和函数
添加参数、返回类型以及描述文档注释了。确保保持初始化函数作为一个声明的函数,这样可以帮助我们生成JSDoc。如果你想看看JSDoc的例子工程,那就在
下载例子。同时这里也有个
,这个也可以作为你构建文档注释时的一部分。
Practice Test-Driven Development
In my opinion, if you’re writing in Backbone.js, you should be following
(TDD) for your models and collections. I follow TDD by first writing failing
unit tests against my models or collections. Once the unit tests are written and failing, I flush out the model or collection.
By this point, all of my Jasmine tests will have been passing, and I have confidence that my model functions all work as expected. Since I’ve been following TDD, my view layer has been super-easy to write and also extremely thin. When you begin practicing TDD, you will
but once you wrap your head around it, your productivity and the quality of your code will dramatically increase.
联系测试驱动的开发模式
我认为如果你用Backbone.js,你应该在开发模型和集合时遵循(TDD)。我第一次用创建模型和集合时遵循TDD进行单元测试,但失败了。一旦写下单元测试并且失败,我会对整个模型和集合进行重写。
通过这一点,我的所有Jasmine测试都通过了,而且我有信心我的模型和集合会和我期望的一样工作。自从我遵循TDD,我的视图层非常容易写而且非常简单。当你开始用TDD时,你得速度当然会很慢;但是一但你得脑海里一直想着TDD,你的编程效率和质量会神奇般的提高。试着用React替换Mustache打造了一个简单的页面,,当然Router用的还是Backbone的Router(react-router似乎还没有做准备好做client-side的Router)。
Backbone RequireJS React 组合
组合的情况以及开发环境如下
IDE: Webstorm(开源license,支持JSX)
Backbone: Router + Model
React: react-with-addons
JSXTransformer
react.backbone
loadsh替换underscore
zepto替换jquery
RequireJS jsx插件
RequireJS管理React依赖
JSX Requirejs
github上有一个插件是:
A RequireJS plugin for JavaScript files containing JSX. It's r.js friendly (i.e. all files containing JSX will be pre-compiled during the r.js build).
于是,安装jsx-requirejs-plugin
bower install jsx-requirejs-plugin --save-dev
Requirejs JSX使用
1.添加paths
react: 'vendor/react-with-addons.min',
&JSXTransformer&: 'vendor/JSXTransformer',
jsx: 'vendor/jsx',
'react.backbone': 'vendor/react.backbone',
2.使用jsx!
require(['jsx!app.react'], function (App) {
最后我的main.js如下所示:
'use strict';
require.config({
jquery: 'vendor/jquery.min',
react: 'vendor/react-with-addons.min',
&JSXTransformer&: 'vendor/JSXTransformer',
jsx: 'vendor/jsx',
'react.backbone': 'vendor/react.backbone',
backbone: 'vendor/backbone',
underscore: &vendor/lodash.min&,
text: 'vendor/text'
underscore: {
exports: '_'
'backbone', 'jsx!app.react'
], function (Backbone, App) {
App.initialize();
换句话说,我们将app.react.js视作app.react.jsx(这里的.react是为了区分js和jsx)。
下面是我的router.react.js
'jsx!router.react'
], function (Router) {
var initialize = function () {
new Router();
initialize: initialize
在我们的router里导入了不同的component,下面是一个精简的router
'use strict';
'underscore',
'backbone',
'react',
'jsx!component/IndexComponent.react',
],function(_, Backbone, React, IndexComponent){
var AppRouter = Backbone.Router.extend({
index: function(){
React.render( &IndexComponent /&, document.getElementById('main_content'));
initialize: function() {
var self = this,
routes = [
[ /^.*$/, 'index' ]
_.each(routes, function(route) {
self.route.apply(self, route);
Backbone.history.start();
return AppR
到此,我们可以愉快地用Requirejs管理我们的component。
完整的Router
我的router如下所示:
'underscore',
'backbone',
'react',
'jsx!component/IndexComponent.react',
'jsx!component/AboutComponent.react',
'jsx!component/ProductComponent.react',
'jsx!component/ProjectComponent.react',
'jsx!component/LibraryComponent.react',
'model/UserModel',
'data/libraries'
],function(_, Backbone, React, IndexComponent, AboutComponent, ProductComponent, ProjectComponent, LibraryComponent, UserModel, libraries){
var AppRouter = Backbone.Router.extend({
index: function(){
React.render( &IndexComponent /&, document.getElementById('main_content'));
about: function(){
React.render( &AboutComponent /&, document.getElementById('main_content'));
product: function(){
React.render( &ProductComponent /&, document.getElementById('main_content'));
library: function(){
React.render( &LibraryComponent items={libraries} /&, document.getElementById('main_content'));
project: function(){
var user = new UserModel({name: 'phodal'});
var UserView = React.createFactory(ProjectComponent);
var userView = new UserView({model: user});
React.render(userView, document.getElementById('main_content'));
initialize: function() {
var self = this,
routes = [
[ /^.*$/, 'index' ],
[ 'about', 'about' ],
[ 'product', 'product' ],
[ 'project', 'project' ],
[ 'library', 'library' ]
_.each(routes, function(route) {
self.route.apply(self, route);
Backbone.history.start();
return AppR
JSXTransformer压缩后的大小&100kb
本文目前还没有评论……

我要回帖

更多关于 ui router 锚点 的文章

 

随机推荐