synthresin
synthresin

Reputation: 931

Observer in DS.Model for an attribute fires when even the attribute is just used in template

I've written an array controller with pagination function.

When I switch to another pages for the first time, there's no problem. But if I reviist the page I visited before, and observer for an attribute that is used is template is triggered. (in this case, published)

When I remove {{#unless published}}...{{/unless}} from template, the observer isn't triggered anymore when I revisit the page where I've already visited.

I don't think I've done weird thing on my controllers....

(When pagination button is clicked, it simply changes controllers's page) (I've written observer for title in model class to test whether this issue is limited to published property, and observer for title also behaves like observer for published. So this issue doesn't seem to limited to published property )

I'm using Ember : 1.7.1+pre.f095a455 Ember Data : 1.0.0-beta.9 Handlebars : 1.3.0 jQuery : 1.11.1 and I tried beta and canary version of ember, but this issue remains same.

might_be_bug

Here is my Route

MuteAdmin.IndexRoute = Ember.Route.extend({
  model: function(params, transition, queryParams) {
    var search = params.search || '';
    var page = params.page || 1;


    return this.store.find(this.get('articleModelClassName'), {
      search: search,
      page: page
    });
  },

  setupController: function(controller, model) {
    controller.set('model', model);
    var will_paginate_meta = model.get("meta.will_paginate");

    controller.set('totalPages', will_paginate_meta.total_pages);
    controller.set('previousPage', will_paginate_meta.previous_page);
    controller.set('nextPage', will_paginate_meta.next_page);
  }
});

and here is my controller

MuteAdmin.IndexController = Ember.ArrayController.extend(MuteAdmin.Modelable, {
  queryParams: ['page', 'search'],
  page: 1,
  totalPages: null,
  pageChanged: function() {
    this.store.find(this.get('articleModelClassName'), {
      search: this.get('search'),
      page: this.get('page')
    }).then(function(model) {
      this.set('model', model);

      var will_paginate_meta = model.get("meta.will_paginate");
      this.set('totalPages', will_paginate_meta.total_pages);
      this.set('previousPage', will_paginate_meta.previous_page);
      this.set('nextPage', will_paginate_meta.next_page);
    }.bind(this));
  }.observes('page'),

  actions: {
    doSearch: function() {
      this.store.find(this.get('articleModelClassName'), {
        search: this.get('search'),
        page: 1
      }).then(function(model) {
        this.set('model', model);

        var will_paginate_meta = model.get("meta.will_paginate");
        this.set('totalPages', will_paginate_meta.total_pages);
        this.set('previousPage', will_paginate_meta.previous_page);
        this.set('nextPage', will_paginate_meta.next_page);
        this.set('page', will_paginate_meta.current_page);
      }.bind(this));
    }
  }
});

and here is my template

{{#each controller}}
    <tr>
      <td>{{link-to title "edit" this}} {{#unless published}}<small class="text-muted">비공개</small>{{/unless}}</td>
      <td>{{author.name}}</td>
      <td>{{category.title}}</td>
      <td>시간 지정</td>
      <td>{{viewCount}}</td>
    </tr>
  {{/each}}

and here is my model which has observers

MuteAdmin.Article = DS.Model.extend({
  title: DS.attr( 'string' ),
  body: DS.attr( 'string' ),
  category: DS.belongsTo('category'),
  author: DS.belongsTo('user'),
  viewCount: DS.attr('number'),
  published: DS.attr('boolean', { defaultValue: true }),
  publishScheduled: DS.attr('boolean', { defaultValue: false }),
  publishScheduleTime: DS.attr('date'),

  publishedChanged: function() {
    if (this.get('published') == true) {
      this.set('publishScheduled', false);
    } 
    console.log('published changed! ' + this.toString());
  }.observes('published'), 
});

Upvotes: 1

Views: 307

Answers (1)

Kingpin2k
Kingpin2k

Reputation: 47367

Never mind, I know what it is. Your making a call to the server for the records that already exist. The results are merging into the pre-existing records in the store causing the model to invalidate and observer to fire.

http://emberjs.jsbin.com/OxIDiVU/1043/edit

Upvotes: 1

Related Questions