
当Angular Material Table的数据源发生变化时,表格没有及时更新,这通常是由于数据源的变更没有被正确地通知给表格。本文将详细介绍如何解决这个问题,确保表格能够正确反映数据的变化。核心在于使用`BehaviorSubject`正确地更新数据流,并触发表格的重新渲染。
Angular Material Table 使用 MatTableDataSource 来绑定数据。当底层数据发生变化时,仅仅修改数据源数组本身,MatTableDataSource 并不会自动检测到这些变化。因此,我们需要手动通知 MatTableDataSource 数据已经更新,从而触发表格的重新渲染。
核心在于使用 BehaviorSubject 来管理数据源,并在数据修改后,通过 next() 方法来推送新的数据,从而通知订阅者(包括 MatTableDataSource)数据已经更新。
在你的 CompanyDataService 中,你已经使用了 BehaviorSubject,这是正确的做法。确保在任何修改 companies 数组的地方,都调用 this.companiesSubject.next(this.companies) 来通知数据变化。
在 editCompanyConnection 方法中,更新 companies 数组后,需要调用 this.companiesSubject.next(this.companies)。
editCompanyConnection(updatedCompany: CompanyConnection): Observable<CompanyConnection[]> {
const index = this.companies.findIndex(c => c.dattoDomain === updatedCompany.dattoDomain);
if (index !== -1) {
this.companies[index] = updatedCompany;
this.companiesSubject.next(this.companies); // 添加这行代码
}
return of(this.companies);
}在你的组件中,通过订阅 companies$ Observable 来获取数据。确保在 ngOnInit 中正确初始化 dataSource。
ngOnInit() {
if (this.getError) {
this.companies$ = this.companyDataService.getErrorCompanyConnections();
} else {
this.companies$ = this.companyDataService.getHealthyCompanyConnections();
}
this.companies$.subscribe((companies: CompanyConnection[]) => {
this.dataSource.data = companies;
});
}通常情况下,使用 BehaviorSubject 和正确的数据绑定后,不需要手动调用 changeDetectorRef.detectChanges()。 如果表格仍然没有更新,可能是其他原因导致,例如数据绑定问题或组件生命周期问题。
下面是修改后的 CompanyDataService 和 CompanyTableComponent 的示例代码:
company-connection-service.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
export interface CompanyConnection {
dattoDomain: string;
connectWiseId: string;
status: string;
}
@Injectable({
providedIn: 'root'
})
export class CompanyDataService {
private companies: CompanyConnection[] = [
{
dattoDomain: "aptdynamics",
connectWiseId: "Apartment Dynamics",
status: "200"
},
{
dattoDomain: "buckscomm",
connectWiseId: "Bucks Communications",
status: "200"
},
{
dattoDomain: "cardinalconcretecompany",
connectWiseId: "Cardinal Concrete Company",
status: "200"
},
{
dattoDomain: "centralcarolinaseeding",
connectWiseId: "Central Carolina Seeding",
status: "404"
},
];
private companiesSubject = new BehaviorSubject<CompanyConnection[]>(this.companies);
constructor() { }
getCompanyConnections(): Observable<CompanyConnection[]> {
return this.companiesSubject.asObservable();
}
getCompanyConnection(dattoDomain: string): Observable<CompanyConnection | undefined> {
return this.getCompanyConnections().pipe(
map((companies: CompanyConnection[]) => {
return companies.find((company: CompanyConnection) => {
return company.dattoDomain === dattoDomain;
});
})
);
}
getHealthyCompanyConnections(): Observable<CompanyConnection[]> {
return this.getCompanyConnections().pipe(
map((companies: CompanyConnection[]) => {
return companies.filter((company: CompanyConnection) => {
return company.status === "200";
});
})
);
}
getErrorCompanyConnections(): Observable<CompanyConnection[]> {
return this.getCompanyConnections().pipe(
map((companies: CompanyConnection[]) => {
return companies.filter((company: CompanyConnection) => {
return company.status !== "200";
});
})
);
}
addCompanyConnection(company: CompanyConnection): Observable<CompanyConnection[]> {
this.companies.push(company);
this.companiesSubject.next(this.companies);
return of(this.companies);
}
editCompanyConnection(updatedCompany: CompanyConnection): Observable<CompanyConnection[]> {
const index = this.companies.findIndex(c => c.dattoDomain === updatedCompany.dattoDomain);
if (index !== -1) {
this.companies[index] = updatedCompany;
this.companiesSubject.next(this.companies); // 添加这行代码
}
return of(this.companies);
}
}company-table.component.ts
import { AfterViewInit, ChangeDetectorRef, Component, Input, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Observable, of } from 'rxjs';
import { CompanyConnection, CompanyDataService } from '../company-connection-service.service';
import { CompanyModalComponent } from '../company-modal/company-modal.component';
@Component({
selector: 'app-company-table',
templateUrl: './company-table.component.html',
styleUrls: ['./company-table.component.css']
})
export class CompanyTableComponent implements OnInit, AfterViewInit {
@ViewChild(MatSort) sort: MatSort;
@Input() companies: CompanyConnection[];
@Input() getError: boolean;
displayedColumns: string[] = ['DattoDomain', 'connectWiseId', 'actions'];
companies$: Observable<CompanyConnection[]> = of([]);
dataSource = new MatTableDataSource<CompanyConnection>();
constructor(
private companyDataService: CompanyDataService,
private dialog: MatDialog,
private changeDetectorRef: ChangeDetectorRef
) {}
ngOnInit() {
if (this.getError) {
this.companies$ = this.companyDataService.getErrorCompanyConnections();
} else {
this.companies$ = this.companyDataService.getHealthyCompanyConnections();
}
this.companies$.subscribe((companies: CompanyConnection[]) => {
this.dataSource.data = companies;
});
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
openEditCompanyModal(company: CompanyConnection) {
const dialogRef = this.dialog.open(CompanyModalComponent, {
data: { company }
});
dialogRef.afterClosed().subscribe((editedCompany: CompanyConnection) => {
if (editedCompany) {
// Update the existing company connection
this.companyDataService.editCompanyConnection(editedCompany).subscribe(
() => {
//Retrieve the updated company connection is not necessary. The table will update automatically.
},
error => {}
);
}
});
}
}通过使用 BehaviorSubject 管理数据源,并在数据修改后调用 next() 方法,可以确保 Angular Material Table 能够正确反映数据的变化。 这种方法简化了数据更新流程,并提高了代码的可维护性。记住,核心在于及时通知数据变化,而不是手动触发表格的重新渲染。
以上就是解决Angular Material Table数据更新问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号