How to keep the url hash when adding pagination to an ember.js web app
-
02-07-2021 - |
Question
I have a simple web app with a table that shows an array of users. The html for this is a basic table showing username / etc
The jsfiddle is here (though when you click the links to paginate jsfiddle seems to reload the page -not what I get locally when I copy/paste the below). But either way it helps show the basic app in action http://jsfiddle.net/Jmj4F/
<script type="text/x-handlebars" data-template-name="application">
<div id="main">
{{ outlet }}
</div>
</script>
<script type="text/x-handlebars" data-template-name="person">
<table width="250px">
<thead>
<th>id</th>
<th>username</th>
<th>update</th>
<th>delete</th>
</thead>
<tbody>
{{#each person in controller}}
<tr>
<td>{{person.id}}</td>
<td>{{view Ember.TextField valueBinding="person.username"}}</td>
<td><input type="submit" value="update" {{action updatePerson person}}/></td>
<td><input type="submit" value="delete" {{action removePerson person}}/></td>
</tr>
{{/each}}
</tbody>
</table>
<div id="pages">
Page.
<a href="/#/page/2">2</a>
<a href="/#/page/3">3</a>
</div>
</script>
My app currently has 2 routes -one that pushes the default view with every user. The second is a simple page route that should slice the array and only show a subset of the users (basic pagination)
PersonApp = Ember.Application.create({});
PersonApp.ApplicationController = Ember.ObjectController.extend({});
PersonApp.ApplicationView = Ember.View.extend({
templateName: 'application'
});
PersonApp.PersonView = Ember.View.extend({
templateName: 'person',
addPerson: function(event) {
var username = event.context.username;
if (username) {
this.get('controller.target').send('addPerson', username);
event.context.set('username', '');
}
}
});
PersonApp.Person = Ember.Object.extend({
username: null
});
PersonApp.PersonController = Ember.ArrayController.extend({
content: [],
page: function(page) {
//in a real app use the page # to slice the array
var newContent = this.content.slice(1,2);
this.set('content', newContent);
}
});
PersonApp.Router = Ember.Router.create({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function(router) {
var first = PersonApp.Person.create({ username: "first" });
var middle = PersonApp.Person.create({ username: "middle" });
var last = PersonApp.Person.create({ username: "last" });
var people = [first,middle,last];
router.get('applicationController').connectOutlet('person', people);
}
}),
page: Ember.Route.extend({
route: '/page/:number',
deserialize : function (router, params) {
var pageNumber = params.number;
router.get('personController').page(pageNumber);
}
})
})
});
$(function () {
PersonApp.initialize(PersonApp.Router);
});
Currently when I click the 2 I see the hash in the url changes from
http://localhost:8000/#/page/2
to
http://localhost:8000/#/page/undefined
This example is still very hello world so I'm open to any improvements here. I'd like to use the router based approach just because it has back button support and that's a plus
Thank you in advance
UPDATE
I finally have a fully paginated / filter / sortable array controller (jsfiddle)
La solution
Looks like I just needed to add a serialize method -now I get the page # instead of undefined
serialize: function(router, context) {
return {
number: context.get('number')
}
}
The only problem with adding this is that context is undefined so I get the following error. What should this method look like?
Uncaught TypeError: Cannot call method 'get' of undefined