DelphiLynx
DelphiLynx

Reputation: 921

Ember.js count position of object in Ember Data Model for simple pagination

I am tryin to count the position of an object. That means which numeric position an item has. That cannot be the primary key because they are not persistent; a record can get deleted.

Asume we have this "model" (a simple array for now, I use Ember Data):

posts = [
  {id: 4, number: 104, title: 'Post 4'},
  {id: 2, number: 102, title: 'Post 2'},
  {id: 3, number: 103, title: 'Post 3'},
];

So at to allow sorting in the postsController we do:

this.controllerFor('posts').set('sortProperties', ['id']); // or maybe just sorting on 'number'
this.controllerFor('posts').set('sortAscending', true);

In the template I want to show the current post and the total number of posts {{currentPostCount}} of {{totalPostCount}}

In postController I have the following computed properties:

App.PostController = Ember.ObjectController.extend({

    posts: function () {
        return this.store.all('posts');
    }.property(),

    currentCount: function () {
        // if there is an id get the position of the record
        // that will be the position count of the post record
        var id = this.get('id');
        if (id) {
            console.log('this item has an id: ' + id);

            var count = 0;
            var currentCount;

            // loop over posts to check at which position the current post is
            this.get('posts').filter(function (item) {

                count++;
                if (item.id == id) {
                    console.log('yay id found! count is: ' + count)
                     currentCount = count;
                }
            });

            return currentCount;
        }
    }.property('posts.@each'),


    totalCount: function () {
        var posts= this.get('posts');
        return posts.get('length');
    }.property('posts.@each')
});

Edit: add model:

App.ApplicationRoute = Ember.Route.extend({
    model: function() {
        this.controllerFor('posts').set('model', this.store.find('post'));
        // sort posts by id
        this.controllerFor('posts').set('sortProperties', ['id']);
        //(...)
    }
});

App.PostsController = Ember.ArrayController.extend();

.

Update: full working simple pagination in Ember.js

In your template:

 <div id="pagination">
      <span>Post {{index}}/{{totalCount}}</span>
      <a {{action previousPost this}} href="#">Previous</a>
      <a {{action nextPost this}} href="#">Next</a>
 </div>

The PostsController:

App.PostsController = Ember.ArrayController.extend({
    sortProperties: ['id'], // I sort on ID, but you can sort on any property you want.
    sortAscending: true,

    assignIndex: function () {
        this.map(function (item, index) {
            Ember.set(item, 'index', index + 1)
        })
    }.observes('content.[]', 'firstObject', 'lastObject')

});

Actions in the PostController:

    previousPost: function (post) {
        var newIndex = (post.index - 1);
        var previousPost = this.store.all('post').findBy('index', newIndex);

        if (previousPost) {
            this.transitionToRoute('post', previousPost);
        }
    },

    nextPost: function (post) {
        var newIndex = (post.index + 1);
        var nextPost = this.store.all('post').findBy('index', newIndex);

        if (nextPost) {
            this.transitionToRoute('post', nextPost);
        }
    }

I have two computed properties in the PostController. However you can better use the following in your PostsController to do it the Ember way, like kingpin2k said. Then you can also omit the posts property.

posts: function () {
    return this.store.all('posts');
}.property(),

// totalcount below the page for pagination
totalCount: function () {
    var posts= this.get('posts');
    return posts.get('length');
}.property('posts.@each'),

Upvotes: 0

Views: 995

Answers (1)

seenivasan
seenivasan

Reputation: 186

You can maintain an index on array content during sorting or removing objects.

In PostsController:

App.PostsController=Em.ArrayController.extend({
    assignIndex:function(){
        this.map(function(item,index){Em.set(item,'index',index+1)})
        }.observes('content.[]','firstObject','lastObject'),
            //other contents to follow...

In posts template the property index is available which is dynamically updated when adding or removing or sorting objects.

In Posts Template:

{{#each controller}}
        <p>{{index}}. {{name}}</p>
{{/each}}

Upvotes: 1

Related Questions