How to add data dynamically to mat-table dataSource?

后端 未结 7 1441
既然无缘
既然无缘 2020-12-08 06:39

I have data streaming from backend and i see it printing in console now i am trying to push event to dataSource its throwing error dataSource is not defined. Ca

相关标签:
7条回答
  • 2020-12-08 06:55

    Here is a very simple and easy solution:

    displayedColumns = ['ticketNum', 'assetID', 'severity', 'riskIndex', 'riskValue', 'ticketOpened', 'lastModifiedDate', 'eventType'];
    dataSource: any[] = [];
    
    constructor() { 
    
    }
    
    ngOnInit() {
    
    }
    
    onAdd() {  //If you want to add a new row in the dataSource
       let model = { 'ticketNum': 1, 'assetID': 2, 'severity': 3, 'riskIndex': 4, 'riskValue': 5, 'ticketOpened': true, 'lastModifiedDate': "2018-12-10", 'eventType': 'Add' };  //get the model from the form
       this.dataSource.push(model);  //add the new model object to the dataSource
       this.dataSource = [...this.dataSource];  //refresh the dataSource
    }
    

    Hope this will help :)

    0 讨论(0)
  • 2020-12-08 07:04

    from the docs

    Since the table optimizes for performance, it will not automatically check for changes to the data array. Instead, when objects are added, removed, or moved on the data array, you can trigger an update to the table's rendered rows by calling its renderRows() method.

    So, you can use ViewChild, and refreshRow()

    @ViewChild('table', { static: true }) table;
      add() {
        this.dataSource.data.push(ELEMENT_DATA[this.index++]);
        this.table.renderRows();
      }
    

    I put together an example in stackblitz

    0 讨论(0)
  • 2020-12-08 07:05

    I was stuck in same problem while creating select row and apply some action over rows data. This solution for your problem

    imports..................
    import { MatTableDataSource } from '@angular/material';
    @component({ ...
    
    export class StreamComponent implements OnInit {
    // Initialise MatTableDataSource as empty
    dataSource = new MatTableDataSource<Element[]>();
    
    constructor() {}
    ...
    // if you simply push data in dataSource then indexed 0 element remain undefined
    // better way to do this as follows
     this.dataSource.data = val as any;
    
      // for your problem
    
       ngOnInit() {
      // ** important note .... I am giving solution assuming the subscription data is array of objects. Like in your case stream and in second event(parameter as callback)
        this.streamService.getAllStream().subscribe(stream => {
           // do it this way
            this.dataSource.data = stream as any;
         // note if you simply put it as 'this.dataSource.data = stream' then TS show you error as '[ts] Type 'string' is not assignable to type '{}[]''
        });
        this.socket.on('newMessage', (event) => {
            console.log('Datasource', event);
              // for this value
           // this.dataSource.MatTableDataSource.filteredData.push(event);   // I couldn't get what you are doing here 
         // SO try to explain what you are getting in this callback function val as event parameter ????????????????? 
         // but you can get it this ways
    
           this.dataSource.filteredData = event as any;
        });
      }
    

    Hope this will help you . If you have any question just ping me.

    0 讨论(0)
  • 2020-12-08 07:07

    I have found a solution for this problem, basically if you do:

    this.dataSource.data.push(newElement); //Doesn't work

    But if you replace the complete array then it works fine. So your final code must be :

    this.socket.on('newMessage', function(event) {
        const data = this.dataSource.data;
        data.push(event);
        this.dataSource.data = data;
    });
    

    You can see the issue here -> https://github.com/angular/material2/issues/8381

    0 讨论(0)
  • 2020-12-08 07:09

    For me, nothing of these answers didn't work. I had an observable that I subscribe to get new data. the only solution that works for me was:

     this.dataService.pointsNodesObservable.subscribe((data) => {
      this.dataSource = new InsertionTableDataSource(this.paginator, this.sort, this.dataService);
      this.dataSource.data = data;
    });
    

    render like a charm!

    0 讨论(0)
  • 2020-12-08 07:15

    You could also use the ES6 spread operator or concat if you are not using ES6+ to assign the dataSource data to a new array.

    In ES6+

    this.socket.on('newMessage', function(event) {
        this.dataSource.data = [...this.dataSource.data, event];
    });
    

    ECMAscript version 3+

    this.socket.on('newMessage', function(event) {
        this.dataSource.data = this.dataSource.data.concat(event);
    });
    
    0 讨论(0)
提交回复
热议问题