如何使用 Angular17 在世界地图中显示可观察函数的值数组

问题描述 投票:0回答:2

我需要一些帮助。我有一个带有 Angular 的 amChart 世界地图,我也有一个可观察的函数,我可以在控制台中显示从 firestore 获取的值,但我无法在地图中显示。

this.countries.map((country) =>
      this.chartService
        .getNumberOfSuppliers(`organizations_${country.toLowerCase()}`)
        .subscribe((num) => {
          this.countryValue = num?.[0]?.num_org;
          // --------   BUG --------------
          // It Show values in console. The values is correct, but no is displaying in the worldchart
          // The value which taking is the default -> 0
          console.log(`${country.toLocaleUpperCase()} :`, this.countryValue); // it show the correct values
        })
    );
    this.data = this.countries.map((country) => ({
      id: country,
      name: this.getCountryName(country),
      value: this.countryValue[country], //Here I need show the values
    }));
getNumberOfSuppliers(s: string): Observable<any> {
    const chartData = collection(this.firestore, s);
    return collectionData(chartData, { idField: 'id' });
  }
angular google-cloud-firestore amcharts
2个回答
0
投票

我认为问题的出现是因为代码流处理不当 尝试以下方法

this.countries.map((country) =>
      this.chartService
        .getNumberOfSuppliers(`organizations_${country.toLowerCase()}`)
        .subscribe((num) => {
          this.countryValue = num?.[0]?.num_org;
          console.log(`${country.toLocaleUpperCase()} :`, this.countryValue);
          this.data = this.countries.map((country) => ({
            id: country,
            name: this.getCountryName(country),
            value: this.countryValue[country],
          }));
        })
    )

此处,this.data 分配将发生在订阅块内,确保在 this.data 中使用之前将正确的值分配给 this.countryValue。

尝试一下并告诉我们


0
投票

您没有获得所需结果的原因是您将

Observable[]
分配给您的
this.data
,而您确实想要实际的数据形状。

首先,我们应该摆脱 .map 循环内的显式订阅,因为它们永远不会被取消订阅。您可以将发出的值“管道”到您想要的形状,而不是订阅。

private requests = this.countries.map(country => this.chartService
    .getNumberOfSuppliers(`organizations_${country.toLowerCase()}`).pipe(
        map(num => num?.[0]?.num_org),
        map(countryValue => ({
            id    : country,
            name  : this.getCountryName(country),
            value : countryValue, 
        }))
    )
);

在这里,我们将每个国家/地区映射到一个可观察的对象中,它将发出您想要的形状(我们称之为

Data
)。所以
requests
Observable<Data>[]

我们可以使用

forkJoin
订阅可观察数组并将其结果作为数组发出。

private sub = forkJoin(requests).subscribe(
   data => this.data = data // here data is Data[]
);

ngOnDestroy() {
  this.sub.unsubscribe();
}

您可以将

.subscribe()
的结果保存在单独的变量中,而只需将其保持为可观察并在模板中使用
async
管道即可。这更简单,因为您不再需要处理取消订阅:

public data$ = forkJoin(requests);
<!-- This is just for displaying the data in the template-->
<pre>
  {{ data$ | async | json }}
</pre>

<!-- But you'd really just pass it as an input to some component -->
<some-component [input]="data$ | async" />
© www.soinside.com 2019 - 2024. All rights reserved.