簡體   English   中英

當模型(在hasMany關聯中)更改時,Ember不更新模板

[英]Ember not updating template when model (in a hasMany association) changes

如果在我的模型中添加/刪除子記錄時,如何強制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

在這里開了一個問題 ,但直到現在還沒有解決。

您的問題是,因為您使用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)...

我希望它有所幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM