Редактировать: я просто не знаю почему, но остановка обнаружения изменений на первом дочернем элементе в иерархии.Если я вручную вызываю обнаружение изменений на один уровень глубже (в 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>
Как видите, таблица владеет массивом JobModel
(s), и каждая строка получает свой собственный JobModel
экземпляр.
JobModel
является оболочкойдля 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>
НаРасширяемая строка У меня есть кнопка, которая позволяет пользователю вводить новое выражение 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()
}
)
}
JobModel#addCronExpression
:
public addCronExpression(cronExpression: string): void {
const cronExpressions = this.formGroup.controls.cronExpressions
cronExpressions.setValue([...cronExpressions.value, cronExpression])
}
Как вы можете видеть, поскольку я не изменяю экземпляр JobModel
, я запускаю detectChanges
, чтобы обновить TableComponent
и его дочерние элементы,sch-job-row-toolbar
включено, я полагаю!
Дело в том, что sch-job-row-toolbar
, похоже, не пересчитывает свои привязки (ngOnChanges не запускается).
Так что тезначения:
[isNew]="jobModel.isNew"
[isEdit]="jobModel.isEdit"
[isError]="jobModel.isError"
[isValid]="jobModel.isValid"
не изменены.
Мы можем взять JobModel#isEdit
в качестве примера:
get isEdit(): boolean {
return this.formGroup.dirty || Job.isEdit(this.job.status)
}
Я понятия не имею, что происходит, но я знаю, что если я это сделаюнажмите кнопку или переключите вкладку в другом месте, sch-job-row-toolbar
получает обновленные значения.
Все компоненты используют стратегию onPush
.
Пояснительный GIF:
И, что интересно, когда я делаю то же самое с первой вкладки, это работает!
Пробовал с использованием Default
стратегии обнаружения изменений, но результат тот же.