我正在学习Angular(实际上几个月前开始学习web开发)。我想显示数据从一个表单到一个表。我有以下模型:
export class Content {
id: number = 0;
title?: string;
subtitle?: string;
content?: string;
date?: string;
media?: string;
}
然后,我有一个表单,其中有一些方法作为onSubmit()
,将数据推入数组。
onSubmit() {
if (this.selectedContent.id === 0) {
this.selectedContent.id = this.contentsList.length + 1;
this.contentsList.push(this.selectedContent);
}
this.selectedContent = new Content();
this.notificationService.success('El postulante se creó correctamente');
console.log(this.contentsList);
}
当我console.logcontentsList
时,它显示了来自表单的新数据,但它没有显示在表中:
dataSource = this.contentsList;
columnsToDisplay = ['title', 'subtitle', 'body', 'date'];
expandedElement: Content | null | undefined;
这是我的表:
<table mat-table [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8">
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let content"> {{content[column]}} </td>
</ng-container>
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
<ng-container matColumnDef="expandedDetail">
<td mat-cell *matCellDef="let element[attr.colspan]="columnsToDisplay.length">
<div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
<div class="example-element-diagram">
<div class="example-element-position"> {{content.title}} </div>
<div class="example-element-symbol"> {{content.subtitle}} </div>
<div class="example-element-name"> {{content.date}} </div>
<div class="example-element-weight"> {{content.body}} </div>
</div>
<div class="example-element-description">
{{content.body}}
<span class="example-element-description-attribution"> </span>
</div>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr mat-row *matRowDef="let content; columns: columnsToDisplay;"
class="example-element-row" [class.example-expanded-row]="expandedElement === content" (click)="expandedElement = expandedElement === content ? null : content">
</tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
</table>
没有关于changeDetectorRef的信息。MatTable的问题是,如果我们添加/删除/更改数据源的一个元素我们需要重新绘制表格参见docs,在关于datasource的API
如果提供了一个数据数组,当该数组的对象被添加、删除或移动时,必须通知表。这可以通过调用renderRows()函数来完成,该函数将呈现自上次表呈现以来的差异。如果数据数组引用被更改,表将自动触发对行
的更新。
所以,如果你的组件中只有一个表你可以使用ViewChild来获取这个表
@ViewChild(MatTable) table:MatTable<any>
所以,当你添加元素时,你使用this.table.renderRows()
。
if (this.selectedContent.id === 0) {
...
this.table.renderRows()
}
但是您需要考虑代码中的另一件事。您可以使用
//the code is WRONG
if (this.selectedContent.id === 0) {
this.contentsList.push(this.selectedContent);
}
this.selectedContent = new Content();
是错误的,因为你正在添加相同的"对象",你需要做一个"复制"。对象的。如果您的对象是一个简单对象,则可以使用spreadOperator进行此复制,因此该函数最终变成
onSubmit() {
if (this.selectedContent.id === 0) {
this.selectedContent.id = this.contentsList.length + 1;
//push a "copy of the object
this.contentsList.push({...this.selectedContent});
this.table.renderRows()
}
this.selectedContent = new Content();
}
可能您在组件中使用了changeDetection
方法。如果您有ChangeDetectionStrategy
,请查看您的ts文件这是示例代码。
@Component({
selector: 'test',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './test.component.html',
styleUrls: ['test.component.scss'],
})
如果你有变更检测,那么有两种方法可以解决这个问题。
只需从组件文件中删除下面的行。
changeDetection: ChangeDetectionStrategy.OnPush
请将以下代码添加到您的ts组件文件中。
在ts文件的顶部导入ChangeDetectorRef
import { ChangeDetectorRef } from '@angular/core';
为构造函数添加一个引用。
constructor(public changeDetectorRef: ChangeDetectorRef) { }
添加在onSubmit
方法末尾的行下面。
this.changeDetectorRef.detectChanges();