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;
}
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
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
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();
});
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 :)
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.
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);
});