簡體   English   中英

Angular - 如何在數組內部觀察到 map

[英]Angular - how to map observable inside array

我有一組服務器object 在該數組中我有另一個可觀察的對象數組,它的鍵是[securityGroups ]。

ngOnInit(): void {
    forkJoin(
      this.serverService.getServer(),
      this.securityGroupService.getSecurityGroups())
      .pipe(takeWhile(() => this.alive))
      .subscribe(([servers, groups]) => {
        this.servers = servers.map((item) => ({
          ...item,
          securityGroups: this.serverService.getServerById(item.id)
            .pipe(map(server => server["security_groups"]))
        }))
        this.securityGroupArray = groups['security_groups'].map((item) => ({
          ...item,
          expanded: false,
        }))
      }

如何從我的服務器陣列中 map 這個[securityGroup] 密鑰 因為它是一個Observable 我不想在 html 中制作異步 pipe,我想將其保存在新數組中

我的服務器陣列有效載荷:

[{id: "1879f47f-1c5e-464b-bb76-e7cc13ef426e", name: "hello", flavor: {…}, securityGroups: Observable}
,
{id: "b9c7e32a-bf99-4250-83cb-13523f9c1604", name: "test01", flavor: {…}, securityGroups: Observable}]

您可以使用forkJoin和 map 將所有內部 observable 解析為server object 的securityGroups屬性

this.serverService.getServer()
.pipe(switchMap((servers) => {
   return from(servers).pipe(mergeMap((server) => {
      return forkJoin(server.securityGroups)
      .pipe(map((_securityGroups) => {
         server.securityGroups =_securityGroups
         return server;
      }))
   }))
}))

如果我理解正確,您的挑戰是您收到一組server並且您需要調用每個服務器以檢索更多數據( securityGroup )並將 append 發送到 object。

為此,您需要以某種方式“訂閱”此輔助調用,以便您可以接收數據。 有幾個“ 高階映射運算符”可以為您執行此操作,因此您不必處理嵌套訂閱。 在這種情況下,我們可以使用switchMap

為了一次進行一堆調用,我們可以使用forkJoin一次進行所有調用並接收所有結果的數組。

您當前正在使用forkJoin進行 2 個不同的調用,但您沒有將這些調用的結果用於相同目的。 我會將它們分成單獨的可觀察對象,既是為了意圖清晰,又可以獨立使用:

  securityGroups$ = this.securityGroupService.getSecurityGroups().pipe(
    map(groups => groups.map(group => ({
      ...group,
      expanded: false
    })))
  );

  servers$ = this.serverService.getServers().pipe(
    switchMap(servers => forkJoin(
      servers.map(s => this.serverService.getServerById(s.id))
    )
    .pipe(
      map(serversWithGroups => serversWithGroups.map((server, i) => ({
        ...servers[i],
        securityGroups: server.security_groups
      }))),
      // shareReplay(1) - see comment below
    ))
  );

如果您願意,您仍然可以訂閱您的 controller:

ngOnInit() {
    this.servers$.subscribe();
    this.securityGroups$.subscribe();
}

或者您可以在模板中使用AsyncPipe

<ng-container *ngFor="let group of securityGroups$ | async">
    <option *ngFor="let server of servers$ | async" [value]="server.id">
        <ng-container *ngFor="let secGroup of server.securityGroups">
            {{ secGroup.name !== group.name ? server.name : '' }}
        </ng-container>
    </option>
</ng-container>

如果您正在嵌套*ngFor ,那么您可以使用shareReplay()運算符來防止多個訂閱多次執行您的服務方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM