Reputation: 410
I have a component that contains a Datatable, this component send an action 'deleteItem' to the Controller in order to delete a specific item by its Id.
The problem is that when I delete an Item from the store the view isn't updated, So my question is how can I refresh the Datatable and show the updated data after a Delete ?
Controller.js
deleteItem(id){
var store = this.get("store");
store.findRecord('foo', id, {backgroundReload: false}).then(function(foo){
foo.deleteRecord();
foo.save().then(
() => {
console.log(`Done !`);
},
(err) => {
console.log(err);
})}
// foo-component.hbs
{{yield}}
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Title</th>
<th>Decription</th>
<th>Category</th>
</tr>
</thead>
<tbody>
{{#each model as |item|}}
<tr>
<td>{{item.title}}</td>
<td>{{item.description}}</td>
<td>{{item.category}}</td>
</tr>
{{/each}}
</tbody>
</table>
//foo-component.js
import Ember from 'ember';
export default Ember.Component.extend({
didInsertElement() {
this.$('table').DataTable({
dom: '<"datatable-header"fl><"datatable-scroll"t><"datatable-footer"ip>',
language: {
search: '<span>Filter:</span> _INPUT_',
lengthMenu: '<span>Show:</span> _MENU_',
manualRowMove: true,
paginate: {
'first': 'First',
'last': 'Last',
'next': '→',
'previous': '←'
}
}
});
this.$('select').select2({
minimumResultsForSearch: Infinity,
width: 'auto'
});
},
actions: {
deleteItem: function(id) {
this.sendAction("deleteItem", id);
}
}
});
Upvotes: 2
Views: 664
Reputation: 339
Once you render an HTML there is no way it will update automatically. So as long as your change does not trigger the component to reflect changes that would not happen. There was one time when I had to solve similar problem, and if I understood you correct. There is refresh method in your route you can invoke after you have updated the store. This would cause the models in your route to be reloaded calling beforeModel()
, model()
and afterModel()
hooks. So when you update the data store, you can use sendAction()
hook to trigger such change, just remember if you cant call refresh()
from any of actions, call a method outside of actions
object and invoke this.refresh()
there.
That shoud work if you are passing data from route without any changes into the controller and eventually to the component, or directly from route to component. However if there are operations you perform in your route before sending the data to this component, the only way to reflect such changes is to update data you pass to controller after executing such operations. For instance like this this.controller.set('fooList', fooList);
. This should update the component if there are any changes in the data received, and will also call all of component life-cycle hooks that get invoked on re-render.
Edited
In your case you have to set new values to the controller
deleteItem(id){
var store = this.get("store");
const self = this;
store.findRecord('foo', id, {backgroundReload: false}).then(function(foo){
foo.deleteRecord();
foo.save().then(
() => {
console.log(`Done !`);
self.refresh();
// here you would update the values for your controller if refresh() does not help you
},
(err) => {
console.log(err);
})}
If you could provide code for model
hook and setUpController
in your rout if you have, it would be easier to explain.
At the least you should understand that updating model
or the controller attributes will trigger updates on components that rely on those values.
Upvotes: 2