2013-12-12 43 views
0

当孩子记录添加/删除到我的模型时,如何强制Ember更新模板?当模型(hasMany关联)发生变化时,注意不要更新模板

客户模式

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,但问题一直没有解决,直到如今。

+0

你能告诉删除和编辑操作? –

+0

我更新了我的问题 – Slevin

+0

我错了,正在更新作品。 – Slevin

回答

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()

可以directlly通过项目实例使用动作{{action "remove" this}}而不是ID {{action "remove" id}}所以没有必要使用重新加载:

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

我希望它能帮助

+0

谢谢!我把我的添加/删除操作放在我的控制器中。我可以从控制器调用loadData方法,还是必须将这些方法放在路由中? – Slevin

+0

你可以在控制器中调用,只是'setupController'会改变,你将需要使用'setupController:function(controller){controller.loadData(); }'在路由中调用控制器方法 –

相关问题