Странное поведение события, испускаемого дочерним компонентом родительскому компоненту - PullRequest
0 голосов
/ 05 января 2019

Я посылаю массив URL-изображений из дочернего компонента в родительский с помощью EventEmitter.

Детский излучатель:

@Output() images  = new EventEmitter<string[]>();

html для родителей:

<app-file-upload (images)="onLoadedImages($event)"></app-file-upload>

где <app-file-upload> - ребенок.

Функция OnLoadedImages () родителя :

  onLoadedImages(images: string[]) {
    console.log(images);
    console.log(images[0]);
  }

Выход на консоль: image of console output

Почему images[0] дает undefined, когда на выходе консоли я вижу, что в нем есть данные, и как я могу получить доступ к images: string[] данным?

Edit:

@ Colby Hunter В качестве ответа на комментарий, вот содержание ребенка:

@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styleUrls: ['./file-upload.component.css']
})
export class FileUploadComponent implements OnInit {

  loadedImagesAsURL = [];
  @Output() images  = new EventEmitter<string[]>();

  constructor() {
  }

  ngOnInit() {
  }

  onFileSelected(event) {
    const filesList = event.target.files;
    for (const file of filesList) {
      const reader = new FileReader();
      reader.onload = (e: any) => {
        this.loadedImagesAsURL.push(e.target.result);
      };
      reader.readAsDataURL(file);
    }
    this.images.emit(this.loadedImagesAsURL);
  }
}
<div class="text-center" *ngIf="loadedImagesAsURL.length>0" style="height: 300px; overflow: auto;">
  <span *ngFor="let image of loadedImagesAsURL">
    <img style="width: 100%;" height="400" src="{{image}}">
  </span>
</div>
<div>
  <input type="file" multiple (change)="onFileSelected($event)" style="display: none;" #fileUpload>
  <button type="button" class="btn btn-secondary" (click)="fileUpload.click()">Wybierz zdjęcia</button>
</div>

1 Ответ

0 голосов
/ 05 января 2019

Консоль браузера выполняет ленивую оценку. Попробуйте сделать:

console.log(JSON.stringify(images));
console.log(images[0]);

вы увидите его как пустой массив.

В вашем случае, когда вы вручную нажимаете на консольный журнал «images», файл загружается и вы видите содержимое.

Поскольку вам необходимо прочитать все файлы и выполнить окончательную эмиссию, сделайте все события чтения файла как наблюдаемые, создайте массив, как только все Обзоры будут завершены.

public onFileSelected(event): void {
    let loadenedObs = this._createFileReaderObs(event);
    forkJoin(...loadenedObs).subscribe(() => {
        // all the files are read, emit the array now.
        this.images.emit(this.loadedImagesAsURL);
   })
}

private _createFileReaderObs(event): [] {
    let obsArr = [];
    const filesList = event.target.files;
    for (const file of filesList) {
      const reader = new FileReader();

      const loadenedEventObs = fromEvent(reader, 'loadend').pipe(
            tap(() => {
                this.loadedImagesAsURL.push(reader.result);
            }),
            take(1)      // take one event to complete the Observable
        );

      obsArr.push(loadenedEventObs);    // create an array of loadened observables.
      reader.readAsDataURL(file);
    }
    return obsArr;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...