Lpp*_*Edd 11 angular-material angular
编辑:我只是不知道为什么,但更改检测在层次结构中的第一个孩子处停止。如果我手动调用更深一层(在 中sch-job-detail)的更改检测,则更新值。
我已经建立了一个MatTable可扩展的行。
“可扩展”行部分如下:
<!-- Hidden cell -->
<ng-container matColumnDef="expandedDetail">
<td mat-cell *matCellDef="let jobModel" [attr.colspan]="displayedColumns.length">
<div
class="detail-cell"
*ngIf="jobModel.isExpanded"
[@detailExpand]
>
<sch-job-detail
[jobModel]="jobModel"
...
></sch-job-detail>
</div>
</td>
</ng-container>
Run Code Online (Sandbox Code Playgroud)
如您所见,该表拥有一个JobModel(s)数组,每一行都接收自己的JobModel实例。
JobModel是 a 的包装器FormGroup,它也是一个简单接口对象的“换位” Job。
sch-job-detail 有其他子组件,例如:
<!-- Toolbar -->
<div class="col">
<sch-job-row-toolbar
[isNew]="jobModel.isNew"
[isEdit]="jobModel.isEdit"
[isError]="jobModel.isError"
[isValid]="jobModel.isValid"
...
></sch-job-row-toolbar>
</div>
Run Code Online (Sandbox Code Playgroud)
在扩张行我有一个按钮,它可以让用户输入一个新的cron表达式,而随后的Cron表达式被添加到FormGroup的FormControl。
里面TableComponent:
public addCronExpression(jobModel: JobModel): void {
this.matDialog
.open<CronDialogSmartComponent, any, string>(CronDialogSmartComponent)
.afterClosed()
.pipe(filter<string>(c => !!c))
.subscribe(c => {
jobModel.addCronExpression(c)
this.changeDetector.detectChanges()
}
)
}
Run Code Online (Sandbox Code Playgroud)
JobModel#addCronExpression:
public addCronExpression(cronExpression: string): void {
const cronExpressions = this.formGroup.controls.cronExpressions
cronExpressions.setValue([...cronExpressions.value, cronExpression])
}
Run Code Online (Sandbox Code Playgroud)
如您所见,由于我没有更改JobModel实例,所以我运行detectChanges以更新TableComponent和它的子项,sch-job-row-toolbar包括我想!
事情sch-job-row-toolbar似乎没有重新计算它的绑定(ngOnChanges 没有运行)。
所以这些值:
[isNew]="jobModel.isNew"
[isEdit]="jobModel.isEdit"
[isError]="jobModel.isError"
[isValid]="jobModel.isValid"
Run Code Online (Sandbox Code Playgroud)
没有改变。
我们可以JobModel#isEdit举个例子:
get isEdit(): boolean {
return this.formGroup.dirty || Job.isEdit(this.job.status)
}
Run Code Online (Sandbox Code Playgroud)
我不知道发生了什么,但我知道如果我按下按钮或在其他地方切换选项卡,则会sch-job-row-toolbar收到更新的值。
所有组件都使用onPush策略。
而且,有趣的是,当我从第一个选项卡做同样的事情时,它起作用了!

尝试使用Default更改检测策略,但结果相同。
小智 2
为什么不使用@Inputand@Output来检测从父组件到子组件的更改?我想建议您使用@Input (parent => child)和 使用@Output (child=> parent) 而不是detectChanges()。