Reputation: 585
First question ever on StackOverflow, how exciting!
Currently I have two custom components, both accepting a couple of input variables :
<sod-matrix-table #matrix
[entities]="entities"
[pairs]="pairs"
[displayedColumns]="displayedColumns">
</sod-matrix-table>
and :
<data-table
#table
[type]="sodMatrixQuery.targetType"
[query]="sodMatrixQuery" >
</data-table>
When updating the entities
, pairs
or columns
of the first tag, everything updates correctly. For example, when I update the displayedColumns
array in a component that uses the matrix table tag, the table inside of that component gets updated with the desired columns.
However, when I update the sodMatrixQuery
in the component, and press the search button, the query
object of the data-table
isn't updated correctly, although they are bound together.
Example:
data-table
has a field query
and uses this query to send REST requests to the server. SODMatrixComponent
has a field sodMatrixQuery
and uses the tag of the data-table
, binding his field to the other field.
An SOD Matrix contains pairs of objects. When I select 2 pairs, and press the search button, the data-table
sends the REST request with 2 pairs. However, when I remove the two pairs, and press search again, the data-table
component sends another REST request, again with 2 pairs instead of none. When pressing the search button a second time, the correct request is send.
I debugged and internally everything with the pairs goes fine, it's only the databinding that doesn't get updated in time. Any thoughts about this?
EDIT: This is the code that happens on the button click:
public search() {
const tempQuery = new SODMatrixQuery(this.lhsType, this.rhsType, [], this.entities);
// Only look at elements above the diagonal
for (let i = 1; i < this.pairs.length; i++) {
for (let j = 0; j < i; j++ ) {
const p = this.pairs[i][j];
if (p.checked) {
tempQuery.addToxicPair(p);
}
}
}
if (this.dataTable) {
this.sodMatrixQuery = tempQuery;
// this.dataTable.query = tempQuery;
this.dataTable.loadDataPage();
}
}
SODMatrixComponent variables :
@ViewChild("table")
public dataTable: ElimityDataTableComponent;
public sodMatrixQuery: SODMatrixQuery;
Datatable component :
@Input()
public query: Query;
SODMatrixQuery extends Query!
The commented line below is a fix, to update the query object directly, but I'm just curious why the databinding doesn't work.
Upvotes: 3
Views: 231
Reputation: 23506
Looks like change detection would need a moment to breathe there - the databinding can't be updated between the setting of the sodMatrixQuery
member and the this.dataTable.loadDataPage()
call - that's why it still has the old value on the first call. After that change detection will be run and on the second call it will have the right values.
if (this.dataTable) {
this.sodMatrixQuery = tempQuery;
// can't update the bindings here
this.dataTable.loadDataPage();
}
So looking at your current architecture, it would be better to move the loadDataPage()
call to the dataTable component into the OnChanges
lifecycle hook, like Agash said in the comments.
export class ElimityDataTableComponent implements OnChanges {
// ...
ngOnChanges(changes: SimpleChanges) {
if (changes.query) {
this.loadDataPage();
}
}
This way, every time you update the sodMatrixQuery
, it automatically loads the new data.
Upvotes: 2