当模型(在hasMany关联中)更改时,Ember不更新模板

时间:2013-12-12 10:55:05

标签: ember.js ember-data

如果在我的模型中添加/删除子记录时,如何强制Ember更新模板?

客户模式

Docket.Customer = DS.Model.extend({
  name:        DS.attr('string'),
  initial:     DS.attr('string'),
  description: DS.attr('string'),
  number:      DS.attr('string'),
  archived:    DS.attr('boolean'),
  projects:    DS.hasMany('project',{ async: true })
});

项目模型

Docket.Project = DS.Model.extend({
  name:        DS.attr('string'),
  description: DS.attr('string'),
  number:      DS.attr('string'),
  archived:    DS.attr('boolean'),
  customer:    DS.belongsTo('customer', { async: true })
});

添加/删除项目时,应更新此模板:

{{#each filteredProjects}}

    <h2>Customer: {{customer.name}}</h2>

    <ul class="entries">

        {{#each projects}}

                <li>
                    <div class="actions">
                        <button {{action "remove" id}} class="icon-close"></button>
                    </div>
                    <div class="link" {{action "edit" id}} data-uk-modal="{target:'#project-modal'}">
                        <span class="before">{{number}}</span>{{name}}
                    </div>
                </li>

        {{else}}
            <li>No projects</li>
        {{/each}}

    </ul>

{{/each}}

示例操作(摘录)

remove: function (id) {
  this.get('store').find('project', id).then(function (data) {
    data.deleteRecord();
    data.save();
  });
},

save: function() {
  // create new record
  var project = this.store.createRecord('project', _this.getProperties('name', 'number', 'description', 'archived'));

  // set customer
  project.set('customer', this.get('selectedCustomer'));

  // validate and save if validation passes, otherwise show errors
  project.save().then(function () {
    _this.closeForm();
  }, function (response) {
    _this.set('errors', response.errors);
  });
}

更新2

openend an issue here,但直到现在才解决。

1 个答案:

答案 0 :(得分:2)

您的问题是,因为您使用map对数据进行分组,所返回的数组不是DS.RecordArray实例,因此在添加或删除项目时,内容不会更新

我认为处理它的简单方法是在添加或删除项目时重新加载数据。因此,请提取加载数据的方法,并在saveremove操作中调用该方法。这里我创建了一个loadData方法:

<强>路线

Docket.OrganizationProjectsIndexRoute = Docket.AuthenticatedRoute.extend({
  setupController: function() {
    this.loadData();
  },
  loadData: function () {

    var projectsController = this.controllerFor('organization.projects');

    this.store.find('customer').then(function(customers) {
      var promises =  customers.map(function(customer) {

        return Ember.RSVP.hash({
          customer: customer,
          projects: customer.get('projects').then(function(projects) {
            return projects.filter(function(project) {
              return !project.get('archived');
            });
          });
        });             

      });

      Ember.RSVP.all(promises).then(function(filteredProjects) {
        projectsController.set('filteredProjects', filteredProjects);
      });

    });            

  },
  actions: {
    remove: function (project) {
      var _this = this;
      project.destroyRecord().then(function() {
        _this.loadData();
      });
    },
    save: function() {
      // create new record
      var project = this.store.createRecord('project', _this.getProperties('name', 'number', 'description', 'archived'));

      // set customer
      project.set('customer', this.get('selectedCustomer'));

      // validate and save if validation passes, otherwise show errors
      projects.save().then(function () {
        _this.closeForm();
        _this.loadData();
      }, function (response) {
        _this.set('errors', response.errors);
      });
    }
  }
});

<强>模板

{{#each filteredProjects}}

    <h2>Customer: {{customer.name}}</h2>

    <ul class="entries">

        {{#each projects}}

                <li>
                    <div class="actions">
                        <button {{action "remove" this}} class="icon-close"></button>
                    </div>
                    <div class="link" {{action "edit" this}} data-uk-modal="{target:'#project-modal'}">
                        <span class="before">{{number}}</span>{{name}}
                    </div>
                </li>

        {{else}}
            <li>No projects</li>
        {{/each}}

    </ul>

{{/each}}

一些提示:

您可以使用project.destroyRecord()代替project.deleteRecord() project.save()

您可以使用{{action "remove" this}}而不是ID {{action "remove" id}}直接将项目实例传递给操作,因此无需使用以下命令重新加载:

this.get('store').find('project', id)...

我希望它有所帮助