简体   繁体   中英

Material Table not reflecting changes on datasource

This is my first question in Stack Overflow. I'll try to be specific but I don't know how to keep this short, so this is going to be a long post. Sorry about that. I promise I searched and tried a lot of stuff before asking, but I'm kind of lost now.

I'm developing a simple app in Angular 6 to keep track of software requisites and the tests associated to those requisites.

  • I have a component, called RequisiteList , whose HTML part consists in a mat-table with an Array of my own Requisite model class as [dataSource]. This array is received as an @Input parameter, and it also has an @Output parameter which is an EventEmitter that notifies and passes to the parent component every time a Requisite on the list is clicked.

  • I make use of RequisiteList inside of ReqListMain , which is a component consisting on the list and a hierarchical tree for filtering. This component is working fine, showing, and filtering requisites as intended. This component also captures the @Output event of the list and passes it as an @Output to its parent.

  • Finally (for what it's related to this question), I have a TestView component that has both an instance of RequisiteList to show the requisites currently associated to current test, and an instance of ReqListMain to add new requisites to current test (like a "browser"). This TestView has an instance of the model class Pectest corresponding to the test that is being currently visualized, which has an array of Requisite .

The idea in this last component was that whenever a requisite of the "browser" list was clicked, it was added to the current test's list. In order to do that, in the callback method associated to the @Output event of the browser list, I tried to add the Requisite received as a parameter:

addrequisite(requisite: Requisite) {
this.currentTest.requisites.push(requisite);
console.log('Current test: ');
console.log(this.currentTest);
}

In the HTML part of TestView , I inserted the RequisiteList component like this:

<app-requisitelist [requisites]="currentTest.requisites" ngModel name="reqlistview"></app-requisitelist>

(The ngModel property is part of the things I've been trying, I'm not sure it's necessary).

The result is:

  • The clicked requisite is not shown in the list.
  • In the console output I can see the content of currentTest object, and I verify that clicked requisites are in fact added to the requisites array of that object, so the event fires and the object is passed upwards by the children components.

I'm not sure if my problem is that data binding is made by value (I don't think so, as I bind an Array, which is an object AFAIK), or the table is not detecting data changes (I've tried to force data change detection with ChangeDetector), or anything else.

You pass a array to the app-requisitelist component. This component waits this array changes to update the content. When you do this.currentTest.requisites.push(requisite) , the array this.currentTest.requisites doesn't change, I mean, if you do

const tmp = this.currentTest.requisites;
this.currentTest.requisites.push(requisite)
if (tmp === this.currentTest.requisites) {
    console.log('The arrays are the same');
}

You will get the log printed. So, I suggest do something like that:

addrequisite(requisite: Requisite) {
    this.currentTest.requisites.push(requisite);
    this.currentTest.requisites = this.currentTest.requisites.map(item => item);
    console.log('Current test: ');
    console.log(this.currentTest);
}

The inserted line forces this.currentTest.requisites to be a new array with the same content.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM