Angular detectChanges не работает на дочернем компоненте - PullRequest
0 голосов
/ 15 января 2019

Редактировать: я просто не знаю почему, но остановка обнаружения изменений на первом дочернем элементе в иерархии.Если я вручную вызываю обнаружение изменений на один уровень глубже (в 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: enter image description here

И, что интересно, когда я делаю то же самое с первой вкладки, это работает!enter image description here

Пробовал с использованием Default стратегии обнаружения изменений, но результат тот же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...