角度变化检测不触发

时间:2020-07-22 13:44:03

标签: angular typescript httpclient

到目前为止,我在多个文件上传组件中工作:

upload.html

<div class="upload-file-wrapper nx-padding-x-2m">
    <ng-container *ngIf="progressFileInfo.length > 0">
        <div class="file-uploaded nx-margin-bottom-m" *ngFor="let progressFile of progressFileInfo">
            <span class="icon-document mpt-icon"></span>
            <div class="file-upload-info nx-padding-x-s">
                <p>{{ progressFile.fileName }}</p>
                <mat-progress-bar *ngIf="progressFile.value != 0 || progressFile.value != 100" mode="determinate" [value]="progressFile.value"></mat-progress-bar>
            </div>
            <button mat-icon-button>
                <span class="icon-trash-can mpt-icon nx-margin-0"></span>
        </button>
        </div>
    </ng-container>
</div>

upload.ts

@Input() serviceId!: string;
@Input() planId!: string;
@Input() set FileSelected(files: FileList) {
    if (files) {
        this.upLoadFiles(files);
    }
}
readonly progressFileInfo: any[] = [];
private readonly _destroyed$ = new Subject<void>();
constructor(
    private readonly resourceManagementService: ResourceManagementService,
    private readonly servicePlanService: ServicePlansService,
    private readonly cd: ChangeDetectorRef,
) {}

ngOnInit() {}

upLoad(index: number, file: File): void {
    this.progressFileInfo[index] = { value: 0, fileName: file.name };
    this.resourceManagementService
        .uploadAdditionalDocument(this.serviceId, this.planId, file)
        .pipe(takeUntil(this._destroyed$))
        .subscribe(
            event => {
                if (event.type === HttpEventType.UploadProgress) {
                    this.progressFileInfo[index].value = Math.round((100 * event.loaded) / event.total);
                    console.log(this.progressFileInfo);
                    this.cd.markForCheck();
                }
            },
            error => {
                this.progressFileInfo[index].value = 0;
                this.progressFileInfo[index].fileName = `Error uploading file - ${this.progressFileInfo[index].fileName}`;
            },
        );
}

upLoadFiles(files: FileList): void {
    Array.from(files).forEach((file: File, index: number) => {
        this.upLoad(index, file);
    });
}

upload.service.ts

uploadAdditionalDocument(serviceId: string, planId: string, file: File): Observable<any> {
    const url = `${this.baseUrl}/${serviceId}/plan/${planId}/api-specification/document`;

    const body: FormData = new FormData();
    body.append('file', file, file.name);

    return this.http.post<{ fileId: string }>(url, body, {
        reportProgress: true,
        responseType: 'json',
        observe: 'events',
    });
}

这个想法是跟踪每个上传文件的进度,并在进度条中显示percentaje,但是由于某种原因,进度条总是100%,当任何请求中有错误时,我都更改名称将该文件设置为“上传文件$ {fileName}时出错”,并将上载%更改为0,但是由于某种原因,视图中未反映任何内容,因此,由于某种原因,未在组件上触发更改检测,如您所见我使用ChangeDetectionRef尝试手动触发更改检测,但视图中没有更改,我忘了说组件正在使用ChangeDetectionStrategy.OnPush

enter image description here

只要不作任何尝试

            if (event.type === HttpEventType.UploadProgress) {
                const c = this.progressFileInfo[index];
                c.value = Math.round((100 * event.loaded) / event.total);
                Object.assign([], this.progressFileInfo, { [index]: c });
                console.log(this.progressFileInfo);
                this.cd.detectChanges();
            }

1 个答案:

答案 0 :(得分:1)

markForCheck不会触发更改检测。默认情况下,它将在角度运行时简单标记下一次要检查的组件。

使用detectChanges()手动触发更改检测 的markForCheck。

此外,由于您要对同一对象进行突变,因此默认情况下不会运行更改检测。 尝试更改对象progressFileInfo的引用,而不是对其进行突变。

if (event.type === HttpEventType.UploadProgress) {
    const exist = this.progressFileInfo;
    exist[index] = { ...exist[index], value: Math.round((100 * event.loaded) / event.total) };
    this.progressFileInfo = [...exist]
    console.log(this.progressFileInfo);
    this.cd.detectChanges();
}
相关问题