wake-up-neo.com

Wie füge ich dynamisch Daten zu mat-table dataSource hinzu?

Ich habe Daten-Streaming vom Backend und ich sehe es in der Konsole drucken. Jetzt versuche ich, das Ereignis auf dataSource zu schieben. Kann jemand helfen, Daten dynamisch hinzuzufügen, um die Tabelle zu materialisieren?

stream.component.html

<mat-table #table [dataSource]="dataSource"></mat-table>

stream.component.ts

import {
    Component,
    OnInit
} from '@angular/core';
import {
    StreamService
} from '../stream.service';
import {
    MatTableDataSource
} from '@angular/material';
import * as io from 'socket.io-client';

@Component({
    selector: 'app-stream',
    templateUrl: './stream.component.html',
    styleUrls: ['./stream.component.css']
})
export class StreamComponent implements OnInit {
    displayedColumns = ['ticketNum', "assetID", "severity", "riskIndex", "riskValue", "ticketOpened", "lastModifiedDate", "eventType"];
    dataSource: MatTableDataSource < Element[] > ;
    socket = io();

    constructor(private streamService: StreamService) {};

    ngOnInit() {
        this.streamService.getAllStream().subscribe(stream => {
            this.dataSource = new MatTableDataSource(stream);
        });
        this.socket.on('newMessage', function(event) {
            console.log('Datasource', event);
            this.dataSource.MatTableDataSource.filteredData.Push(event);
        });
    }
}


export interface Element {
    ticketNum: number;
    ticketOpened: number;
    eventType: string;
    riskIndex: string;
    riskValue: number;
    severity: string;
    lastModifiedDate: number;
    assetID: string;
}
12
hussain

Ich habe eine Lösung für dieses Problem gefunden, im Grunde genommen, wenn Sie dies tun:

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

Aber wenn Sie das gesamte Array ersetzen, funktioniert es einwandfrei. Ihr endgültiger Code muss also sein:

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

Sie können das Problem hier sehen -> https://github.com/angular/material2/issues/8381

30
Jose Luis

aus dem docs

Da die Tabelle für die Leistung optimiert ist, wird nicht automatisch nach Änderungen am Datenarray gesucht. Stattdessen können Sie beim Hinzufügen, Entfernen oder Verschieben von Objekten im Datenarray eine Aktualisierung der gerenderten Zeilen der Tabelle auslösen, indem Sie die renderRows () -Methode aufrufen.

Sie können also ViewChild und refreshRow () verwenden.

@ViewChild('table', { static: true }) table
  add() {

    this.dataSource.data.Push(ELEMENT_DATA[this.index++])
    this.table.renderRows()
  }

Ich habe ein einfaches Beispiel in stackblitz eingefügt

2
Eliseo

Die folgende Lösung hat für mich auf Angular 5.2.3 und Angular Material 5.1.1 funktioniert:

this.socket.on('newMessage', function(event) {
    this.dataSource.data.Push(event);
    this.dataSource.data = this.dataSource.data.slice();
});
0
andreivictor

Hier ist eine sehr einfache und einfache Lösung:

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
}

Hoffe das wird helfen :)

0
SKB

Ich war beim Erstellen der Auswahlzeile in demselben Problem und wende eine Aktion auf die Zeilendaten an. Diese Lösung für Ihr 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;
    });
  }

Hoffe, das wird dir helfen. Wenn Sie eine Frage haben, ping mich einfach. 

0
Vikas Kumar

Anstatt in ein separates Array zu pushen und dieses dann den dataSource Daten zuzuweisen, könnten wir einfach den ES6-Spread-Operator oder concat verwenden, wenn Sie nicht ES6 + verwenden, um die dataSource Daten in ein neues 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
nash11