angular - 找不到在 Angular 8 组件中返回对象数组的方法
问题描述
我是 Angular 8 的新手。我正在服务中创建一个方法,该方法允许我返回动态构造的数据结构。
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AppConfig } from 'src/app/app.config';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class BibliographyParserService {
private editionUrls = AppConfig.evtSettings.files.editionUrls || [];
private bibliographicCitations: Array<BibliographicCitation> = [];
constructor(
private http: HttpClient,
) {
}
public getBibliographicCitations() {
const parser = new DOMParser();
this.editionUrls.forEach((path) => {
this.http.get(path, { responseType: 'text' }).pipe(map((response: string) => {
Array.from(parser.parseFromString(response, 'text/xml').getElementsByTagName('bibl')).forEach(citation => {
if (citation.getElementsByTagName('author').length === 0 &&
citation.getElementsByTagName('title').length === 0 &&
citation.getElementsByTagName('date').length === 0) {
const interfacedCitation: BibliographicCitation = {
title: citation.textContent.replace(/\s+/g, ' '),
};
if (!this.bibliographicCitations.includes(interfacedCitation)) { this.bibliographicCitations.push(interfacedCitation); }
} else {
const interfacedCitation: BibliographicCitation = {
author: citation.getElementsByTagName('author'),
title: String(citation.getElementsByTagName('title')[0]).replace(/\s+/g, ' '),
date: citation.getElementsByTagName('date')[0],
};
if (!this.bibliographicCitations.includes(interfacedCitation)) { this.bibliographicCitations.push(interfacedCitation); }
}
});
this.bibliographicCitations.forEach(biblCit => {
console.log(((biblCit.author === undefined) ? '' : biblCit.author),
((biblCit.title === undefined) ? '' : biblCit.title),
((biblCit.date === undefined) ? '' : biblCit.date));
});
}),
);
});
// THIS IS RETURNED EMPTY IN THE COMPONENT WHEN ACTUALLY IT IS FULL!
return this.bibliographicCitations;
}
}
export interface BibliographicCitation {
author?: HTMLCollectionOf<Element>;
title: string;
date?: Element;
}
在我查阅的文档中,我注意到没有这样的“复杂”示例,因为我想要获取的数据在http
调用中,而调用又在循环中!我显然想在循环完成后归还它们。
如果我用 调用外部方法console.log(this.bps.getBibliographicCitations())
,它现在返回一个空数据结构:
[]
length: 0
__proto__: Array(0)
我想知道是否有办法通过避免立即subscribe
进入服务来返回数据。
解决方案
我们在这里要做的是使用普通的 javascriptmap
函数返回一个可观察的 http 调用流。
public getBibliographicCitations() {
return this.editionUrls.map((path) => this.http.get(path, { responseType: 'text'
}));
}
然后要获取值,我们必须订阅它,因为 observables 总是惰性的。要订阅,我们可以执行以下操作:
import { forkJoin } from 'rxjs';
forkJoin(this.getBibliographicCitations()).subscribe(console.log);
在这里,我使用forkJoin它将等待您的所有 api 调用。一旦一切成功,您将能够在控制台中看到数据。
无论您需要映射或操作从响应中获得的值,您都应该在订阅函数中执行该操作,如下所示
forkJoin(this.getBibliographicCitations()).subscribe((responses) => {
// Update instance variables accordingly
this.bibliographicCitations = //;
});
谢谢