jd.
jd.

Reputation: 4098

Ember.js - filtered model change does not trigger a change in rendered template

I have an application that prints a list of reservations. There are 2 routes:

reservations.allReservations

reservations.newReservations

The Problem:

The allReservations route works fine. If reservations are deleted or added, it is reflected automatically on the page. However, the newReservations route does not get refreshed on changes - however if I reload the page the changes are there.

The setup:

The main difference between the two is the routes model field. For the allReservation route it is:

App.Reservations.all();

for the newReservation route it is:

App.Reservations.all().filterProperty('isNew',true);

The application models and data store is setup as in the Ember.js version of the TodoMVC app.

Route:

App.ReservationsNewReservationsRoute = Em.Route.extend({

model: function(){
       return App.Reservation.all().filterProperty('isNew', true);
    },

    renderTemplate: function(){
       this.render('reservationList');
    },
});

Controller:

App.ReservationsNewReservationsController = Ember.ArrayController.extend({

    isEmpty: function() { 
        return this.get( 'length' ) == 0;
    }.property( '@each.length', '@each.isNew'),

});

Template reservationList.hbs:

{{#if isEmpty}}
    <li>
        <div class="text-center" style="height: 40px; margin: auto 0;">
            <label>No Reservations!</label>
        </div>
    </li>
{{/if}}
{{#each controller}}
   ... print reservations ...
{{/each}}

Upvotes: 2

Views: 1205

Answers (1)

sly7_7
sly7_7

Reputation: 12011

In order to use a filtered array, I think you must use

model: function(){
   return App.Reservations.filter(function(reservation){
     return reservation.get('isNew') === true;
   });
});

which returns a live FilteredRecordArray, updated when there is a new reservation loaded in the store.

When you use filterProperty(), you loose the FilteredRecordArray, and then the resulted array is not live.

Since you're not using ember-data, you have to manually maintain the filter. I think there could be to way of doing this.

The simplest would be to add a computed property on the controller, which would return the filtered content, and populating the model with App.reservations.all() Obviously in the template, you will use {{#each controller.filteredContent}} Something like:

App.ReservationsNewReservationsController = Ember.ArrayController.extend({

  isEmpty: function() { 
    return this.get( 'filtered.length' ) == 0;
  }.property('filtered.length'),

  //will be evaluated each time a reservation is added/removed, 
  //or each time a reservation's isNew property changed.
  filteredContent: function(){
     return this.get('content').filterProperty('isNew', true);
  }.property('@each.isNew')
});

The other solution could be to add the filter method on the Reservation model, and consistently in the store.

Upvotes: 2

Related Questions