Обнаружение изменений onPush всегда на 1 элемент позади при добавлении элементов в массив - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть компонент загрузки, где пользователь может выбирать файлы.Я рефакторинг на onPush, но я испытываю странное поведение:

export class FileUploadComponent implements OnInit, OnDestroy {
  files$: BehaviorSubject<FileToUpload[]> = new BehaviorSubject([]);
  readonly files: Observable<FileToUpload[]> = this.files$.asObservable();
  fileStateSubscription: Subscription;
  uploadCandidates$: Subscription;

  activeFiles: FileToUpload[];
  canUpload: boolean;
  isUploading: boolean;

  constructor(
    private uploadService: UploadService
  ) {}

  ngOnInit() {
    this.uploadService.study$.take(1).subscribe((study) => (this.study = study));
    this.uploadService.currentUser$.take(1).subscribe((currentUser) => (this.currentUser = currentUser));

    this.fileStateSubscription = this.files.subscribe((files) => {
      this.activeFiles = files.filter((f) => f.state !== FileUpLoadState.success);
      this.canUpload = files.length > 0 && files.every((f) => f.state === FileUpLoadState.new && f.isValid);
      this.isUploading = files.length > 0 && files.some((f) => f.state === FileUpLoadState.uploading);
    });
  }

  async upload(event: Event) {
    const fileList: FileList = (event.target as HTMLInputElement).files;

    this.uploadActions.clearUploadCandidates();

    if (!fileList.length) {
      return;
    }

    let files: FileToUpload[];

    files = await this.uploadService.upload(this.files$.getValue(), fileList);

    this.files$.next(this.files$.getValue().concat(files));

    setTimeout(() => {
      this.uploadButtonRef.fileInputRef.nativeElement.value = '';
    });
  }
}

При первом нажатии на шаблон отображается 0, хотя fileState.activeFiles имеет длину 1, а следующийкогда я нажимаю, отображается 1, хотя fileState.activeFiles имеет длину 2.

Если я удаляю changeDetection: ChangeDetectionStrategy.OnPush, тогда все работает, как ожидалось.

Если изменить мойвведите ChangeDetectorRef, а затем измените мою подписку следующим образом:

this.fileStateSubscription = this.files$.subscribe((files) => {
  this.activeFiles = files.filter((f) => f.state !== FileUpLoadState.success);
  this.canUpload = files.length > 0 && files.every((f) => f.state === FileUpLoadState.new && f.isValid);
  this.isUploading = files.length > 0 && files.some((f) => f.state === FileUpLoadState.uploading);
  this._changeDetector.markForCheck();
});

Тогда это сработает, но я думаю, что это побеждает цель, если мне нужно явно пометить каждое изменение.

Это потому, что код, который вызывает next, является функцией async?

Что я делаю не так?

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