2013-12-12 40 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(); }'在路由中調用控制器方法 –

相關問題