Angular: Как получить асин c данные для шаблона - PullRequest
0 голосов
/ 27 апреля 2020

У меня следующая проблема:

Я хочу сделать таблицу с записями (Obj). И некоторые из них имеют атрибут файла. Если у них есть атрибут файла (entry.file), я хочу сделать внутренний вызов, чтобы получить URL этого файла:

public getFileURL(archiveID: string, documentID: string, sysID: string){
    const request: FileRequest = {
      archiveID: archiveID,
      documentID: documentID,
      sysID: sysID
    };
    this.fileService.file(request).subscribe(response => {
      if (response) {
        return response;
      }
    })
}

Это называется как: getFileURL (entry.file.archiveID, entry. file.documentID, entry.file.sysID) И он должен возвращать Observable, чтобы я мог проверить, получил ли я ответ бэкэнда.

<tr *ngFor="let entry of period.claims; let i = index">
...
<td>
  <div *ngIf="entry.file">
    <div *ngIf="fileClientService.getFileURL(entry.file.archiveID, entry.file.documentID, entry.file.sysID) | async as file; else loading">
      <a target="about:blank" class="download" (click)="clickLink(file)"></a>
    </div>
    <ng-template #loading let-file>loading..</ng-template>
  </div>
</td>

Все, что я хочу, это отображать «loading», пока URL загружен, а затем отобразите a-tag. Кроме того, параметр url, возвращаемый из серверной части, может быть пустым. Поэтому мне также нужно ничего не отображать, если URL-адрес пуст (""). В настоящий момент он запускает сотни внутренних вызовов для 2 объектов со свойством entry.file: (

Я не очень хорош в Observables, и я надеюсь, что кто-то может мне помочь с этим. Спасибо вам пока:)

1 Ответ

1 голос
/ 27 апреля 2020

Вам нужно вернуть Observable непосредственно из вашего метода и отобразить ваш period.claims в один Observable:

// add proper type
entries: Observable<...> = getEntries();

getEntries() {
  // we map every claim to Observable returned from getFileURL method
  const entries = period.claims.map(entry => 
    getFileURL(...).pipe(
      // we use map to return whole entry from Observable - not only url
      map(url => ({
        ...entry,
        url,
      }))
  ));
  // forkJoin will return one Observable with value array when each Observable is completed
  return forkJoin(...entries);
}

public getFileURL(archiveID: string, documentID: string, sysID: string): Observable<...> {
    const request: FileRequest = {
      archiveID: archiveID,
      documentID: documentID,
      sysID: sysID
    };
    return this.fileService.file(request).pipe(filter(Boolean));
}

Если вы не хотите переходить к пустому ответу шаблона, вы можете использовать filter оператор и передать логическое значение в качестве обратного вызова. Он вернет только истинные значения. Вы можете прочитать больше об этом: https://www.learnrxjs.io/learn-rxjs/operators/filtering/filter Вы можете прочитать больше о forkJoin: https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin

Обратите внимание, что добавление правильного типа в метод скажет ты что делаешь не так;)

...