Define a Router
A Backbone router defines navigation paths among views. To learn more about routers, see What is a router?
-
In the final <script> block, define the application
router by extending Backbone.StackRouter.
1app.Router = Backbone.StackRouter.extend({ 2 3});For the remainder of this procedure, add all code in the extend({}) block.
-
Because the app supports a search list page and a user page, add a route for each page inside a
routes object. Also add a route for the
main container page ("").
1routes: { 2 "": "list", 3 "list": "list", 4 "users/:id": "viewUser" 5}, -
Define an initialize() function that creates the search
results collection and the search page and user page views.
1initialize: function() { 2 Backbone.Router.prototype.initialize.call(this); 3 4 // Collection behind search screen 5 app.searchResults = new app.models.UserCollection(); 6 7 app.searchPage = new app.views.SearchPage( 8 {model: app.searchResults}); 9 app.userPage = new app.views.UserPage(); 10}, -
Define the list() function for handling the only item in
this route. Call slidePage() to show the
search results page right away—when data arrives, the list redraws
itself.
1list: function() { 2 app.searchResults.fetch(); 3 this.slidePage(app.searchPage); 4}, -
Define a viewUser() function that fetches
and displays details for a specific user.
1viewUser: function(id) { 2 var that = this; 3 var user = new app.models.User({Id: id}); 4 user.fetch({ 5 success: function() { 6 app.userPage.model = user; 7 that.slidePage(app.userPage); 8 } 9 }); 10} - After saving the file, run the cordova prepare command.
- Run the application.
Example
You’ve finished! Here’s the entire application:
1<!DOCTYPE html>
2<html>
3<head>
4<title>Users</title>
5<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
6<link rel="stylesheet" href="css/styles.css"/>
7<link rel="stylesheet" href="css/ratchet.css"/>
8</head>
9
10<body>
11
12<div id="content"></div>
13<script src="js/jquery.min.js"></script>
14<script src="js/underscore-min.js"></script>
15<script src="js/backbone-min.js"></script>
16
17<!-- Local Testing -/->
18<script src="js/MockCordova.js"></script>
19<script src="js/cordova.force.js"></script>
20<script src="js/MockSmartStore.js"></script>
21<!-- End Local Testing -->
22
23<!-- Container -->
24<script src="cordova.js"></script>
25<!-- End Container -->
26
27<script src="js/force.js"></script>
28<script src="js/force+promise.js"></script>
29<script src="js/mobilesync.js"></script>
30<script src="js/fastclick.js"></script>
31<script src="js/stackrouter.js"></script>
32<script src="js/auth.js"></script>
33
34
35<!-- ----Search page template ---- -->
36<script id="search-page" type="text/template">
37 <header class="bar-title">
38 <h1 class="title">Users</h1>
39 </header>
40
41 <div class="bar-standard bar-header-secondary">
42 <input type="search"
43 class="search-key"
44 placeholder="Search"/>
45 </div>
46
47 <div class="content">
48 <ul class="list"></ul>
49 </div>
50</script>
51
52<!-- ---- User list item template ---- -->
53<script id="user-list-item" type="text/template">
54
55 <a href="#users/<%= Id %>" class="pad-right">
56 <img src="<%= SmallPhotoUrl %>" class="small-img" />
57 <div class="details-short">
58 <b><%= FirstName %> <%= LastName %></b><br/>
59 Title<%= Title %>
60 </div>
61 </a>
62</script>
63
64<!-- ---- User page template ---- -->
65<script id="user-page" type="text/template">
66 <header class="bar-title">
67 <a href="#" class="button-prev">Back</a>
68 <h1 class="title">User</h1>
69 </header>
70
71 <footer class="bar-footer">
72 <span id="offlineStatus"></span>
73 </footer>
74
75 <div class="content">
76 <div class="content-padded">
77 <img id="employeePic"
78 src="<%= SmallPhotoUrl %>" class="large-img" />
79 <div class="details">
80 <b><%= FirstName %> <%= LastName %></b><br/>
81 <%= Id %><br/>
82 <% if (Title) { %><%= Title %><br/><% } %>
83 <% if (City) { %><%= City %><br/><% } %>
84 <% if (MobilePhone) { %>
85 <a href="tel:<%= MobilePhone %>">
86 <%= MobilePhone %></a><br/><% } %>
87 <% if (Email) { %>
88 <a href="mailto:<%= Email %>">
89 <%= Email %></a><% } %>
90 </div>
91 </div>
92 </div>
93</script>
94
95<script>
96// ---- The Models ---- //
97// The User Model
98app.models.User = Force.SObject.extend({
99 sobjectType: "User",
100 fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl",
101 "Title", "Email", "MobilePhone","City"]
102});
103
104// The UserCollection Model
105app.models.UserCollection = Force.SObjectCollection.extend({
106 model: app.models.User,
107 fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl",
108 "Title"],
109
110 getCriteria: function() {
111 return this.key;
112 },
113
114 setCriteria: function(key) {
115 this.key = key;
116 this.config = {type:"soql",
117 query:"SELECT "
118 + this.fieldlist.join(",")
119 + " FROM User"
120 + " WHERE Name like '" + key + "%'"
121 + " ORDER BY Name "
122 + " LIMIT 25 "
123 };
124 }
125});
126
127
128// -------------------------------------------------- The Views ---------------------------------------------------- //
129
130app.views.SearchPage = Backbone.View.extend({
131
132 template: _.template($("#search-page").html()),
133
134 events: {
135 "keyup .search-key": "search"
136 },
137
138 initialize: function() {
139 this.listView =
140 new app.views.UserListView(
141 {model: this.model});
142 },
143
144 render: function(eventName) {
145 $(this.el).html(this.template());
146 $(".search-key", this.el).val(this.model.getCriteria());
147 this.listView.setElement($("ul", this.el)).render();
148 return this;
149 },
150
151 search: function(event) {
152 this.model.setCriteria($(".search-key", this.el).val());
153 this.model.fetch();
154 }
155});
156
157app.views.UserListView = Backbone.View.extend({
158
159 listItemViews: [],
160
161 initialize: function() {
162 this.model.bind("reset", this.render, this);
163 },
164
165 render: function(eventName) {
166 _.each(this.listItemViews,
167 function(itemView) {itemView.close(); });
168 this.listItemViews =
169 _.map(this.model.models, function(model) {
170 return new app.views.UserListItemView(
171 {model: model}); });
172 $(this.el).append(_.map(this.listItemViews,
173 function(itemView) {
174 return itemView.render().el;} ));
175 return this;
176 }
177});
178
179app.views.UserListItemView = Backbone.View.extend({
180
181 tagName: "li",
182 template: _.template($("#user-list-item").html()),
183
184 render: function(eventName) {
185 $(this.el).html(this.template(this.model.toJSON()));
186 return this;
187 },
188
189 close: function() {
190 this.remove();
191 this.off();
192 }
193});
194
195app.views.UserPage = Backbone.View.extend({
196
197 template: _.template($("#user-page").html()),
198
199 render: function(eventName) {
200 $(this.el).html(this.template(this.model.toJSON()));
201 return this;
202 }
203
204});
205
206
207// ----------------------------------------------- The Application Router ------------------------------------------ //
208
209app.Router = Backbone.StackRouter.extend({
210
211 routes: {
212 "": "list",
213 "list": "list",
214 "users/:id": "viewUser"
215 },
216
217 initialize: function() {
218 Backbone.Router.prototype.initialize.call(this);
219
220 // Collection behind search screen
221 app.searchResults = new app.models.UserCollection();
222
223 // We keep a single instance of SearchPage and UserPage
224 app.searchPage = new app.views.SearchPage(
225 {model: app.searchResults});
226 app.userPage = new app.views.UserPage();
227 },
228
229 list: function() {
230 app.searchResults.fetch();
231 // Show page right away
232 // List will redraw when data comes in
233 this.slidePage(app.searchPage);
234 },
235
236 viewUser: function(id) {
237 var that = this;
238 var user = new app.models.User({Id: id});
239 user.fetch({
240 success: function() {
241 app.userPage.model = user;
242 that.slidePage(app.userPage);
243 }
244 });
245 }
246});
247</script>
248</body>
249</html>