Don't need more define route actions inside Backbone Router.
With standart Backbone.Router your have to write long list of routes for each action of your app, and worse, you have to define transit actions for each route inside Router function which as a rule just trigger special events and it handled in other Views. So why we need these extra functions in Router and events handlers in Views? What about declarative relation between resource routes and View-actions like in Rails router? And what about declarative redirects in a single line of code also without router actions? With Backbone.Resources you can do this and some more! Features of Backbone.Resources:
- Resource Routing like in Rails. Your declare in a single line of code all routes for one resource and bind it with special View that service it.
- Resource route action when matching will automaticly call same name method of resources View. Dont need define actions inside Router!
- All Resources.View have default
render()
method and calls it after each action method call. Torender()
method will be automaticly passed all params from route and you can use it in template. - On each route will be created a helper funtion for easy generating urls in templates. Dont need hardcode urls in strings!
- Declarative redirects in a single line without uses Router actions.
- If you use JST, just set path to resource and templates for all actions will be setting automaticly.
Download source from GitHub.
- Development: backbone-resources.js 7.273 kb
- Production: backbone-resources.min.js 3.351 kb
Include plugin in HTML and create skeleton something like this (example):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Backbone.Resources demo</title>
<script type="text/javascript" src="../../vendor/jquery.min.js"></script>
<script type="text/javascript" src="../../vendor/underscore.js"></script>
<script type="text/javascript" src="../../vendor/backbone.js"></script>
<script type="text/javascript" src="../../build/backbone-resources.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<div id="app">
Loading....
</div>
<!-- Posts resource templates -->
<script type="text/template" id="posts-edit">
<!-- Edit action template... -->
</script>
<script type="text/template" id="posts-index">
<!-- Index action template... -->
</script>
<script type="text/template" id="posts-new">
<!-- New action template... -->
</script>
<script type="text/template" id="posts-show">
<!-- Show action template... -->
</script>
</body>
</html>
PostsView = Resources.View.extend({
el: "#app",
initialize: function() {
},
index: function() {
this.template = _.template($('#posts-index').text());
},
new: function() {
this.template = _.template($('#posts-new').text());
},
// Auto-define this.params with :id from router
show: function() {
this.template = _.template($('#posts-show').text());
},
// Auto-define this.params with :id from router
edit: function() {
this.template = _.template($('#posts-edit').text());
}
});
Router = Resources.Router.extend({
resources: {
posts : {view: PostsView, actions: ['index', 'new'], item_actions: ['show', 'edit']}
},
redirects: {
".*" : "posts",
"e/:id" : "posts/:id/edit"
}
});
// Init router
$(function() {
router = new Router();
Backbone.history.start();
});
-
On matching route
#posts/new
will be callednew
action ofPostsView
and after callrender()
with_.template($('#posts-new').text())
. -
On matching
#posts/2/edit
be callededit
action andrender()
with_.template($('#posts-edit').text())
and params{id: 2}
. -
Root route will be redirected to
#posts
and#e/2/
will be redirected to#posts/2/edit
. -
For each resource routes will be created helper method for simple generating route url.
// Example:
posts_path() // => '#posts'
new_post_path() // => '#posts/new'
post_path(12) // => '#posts/12'
edit_post_path(12) // => '#posts/12/edit'
No problem. Use JST for declarate resource templates and forget about it.
App.Views.Posts = Resources.View.extend({
el: "#app",
// Auto-define this.template = JST["backbone/templates/posts/:action"] in each action and use it in render.
JSTpath: "backbone/templates/posts",
....
index: function() {
},
new: function() {
},
....
As you wish. For skip render()
callback just call this.skipRender();
in your action.
For using custom template engine, for example Handlebars, just set compiled template to this.template
in action:
....
index: function() {
this.template = Handlebars.compile(source);
},
...
If you dont wana bind any View with routes just dont set view:
in resource:
...
resources: {
posts : {actions: ['index', 'new'], item_actions: ['show', 'edit']}
},
...
and Router just will be trigger action events on itself like routes:posts:edit
with url params. This is also very useful.