xml 파일을 처리하고 인터페이스의 데이터 구조를 반환하는 서비스를 개발 중입니다.
처음에는 서비스가 모든 데이터를 올바르게 반환했다고 생각했지만 특히 구성 요소의 데이터 구조를 읽으려고 할 때 명확하지 않은 점을 깨달았습니다.
이것은 내 서비스입니다.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AppConfig } from 'src/app/app.config';
import { forkJoin, Subscription } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class BibliographyParserService {
private editionUrls = AppConfig.evtSettings.files.editionUrls || [];
private bibliographicCitations: Array<BibliographicCitation> = [];
private subscriptions: Array<Subscription> = [];
constructor(
private http: HttpClient,
) {
}
private getHttpCallsOBSStream() {
return this.editionUrls.map((path) => this.http.get(path, { responseType: 'text'}));
}
public getBibliographicCitations(): Array<BibliographicCitation> {
const parser = new DOMParser();
this.subscriptions.push(forkJoin(this.getHttpCallsOBSStream()).subscribe((responses) => {
responses.forEach(response => {
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 = {
authors: 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); }
}
});
});
}));
return this.bibliographicCitations;
}
}
export interface BibliographicCitation {
authors?: HTMLCollectionOf<Element>;
title: string;
date?: Element;
}
그리고 이것은 내 구성 요소입니다.
import { Component, AfterViewInit } from '@angular/core';
import { BibliographyParserService } from 'src/app/services/xml-parsers/bibliography-parser.service';
@Component({
selector: 'evt-bibliography',
templateUrl: './bibliography.component.html',
styleUrls: ['./bibliography.component.scss']
})
export class BibliographyComponent implements AfterViewInit{
constructor(
public bps: BibliographyParserService,
) {
console.log(this.bps.getBibliographicCitations()); // WORKS, return the correct data structure
this.bps.getBibliographicCitations().forEach(console.log); // DOESN'T RETURN ANYTHING!
console.log(this.bps.getBibliographicCitations().length); // RETURN 0
}
ngAfterViewInit() {
(document.querySelectorAll('.cloosingRood')[0] as HTMLElement).onclick = () => {
(document.querySelectorAll('.biblSpace')[0] as HTMLElement).style.display = 'none';
};
}
}
아주 이상한 것은 그 세 개의 통나무입니다. 우리는 그들 사이에서 다른 것을 볼 수 있습니다.
첫 번째 로그를 사용하면 콘솔에서 전체 데이터 구조를 볼 수 있습니다.
두 번째로는 아무 일도 일어나지 않습니다.
세 번째의 경우 길이는 0과 같으며 첫 번째 로그에 표시된 것처럼 데이터 구조가 가득 차서 사실이 아닙니다 ...!
나는 왜 이러한 기이함을 이해하지 못한다. 각도 문서에서 놓친 것이 있습니까?
추신 : 구성 요소에서 구독을 만들고 싶지 않습니다. 그렇지 않으면 이미 해결했을 것입니다. 나처럼 시각화에서 논리를 분리하고 서비스에서 데이터 구조를 만들고 싶습니다.
서비스에 가입 할 필요는 없지만 Observable을 반환합니다.
당신이 그것을 만드는 방법은 무관심합니다. 중요한 것은 각도 초보자에게는 이해하기 쉽지 않은 구문을 존중하는 것입니다!
의 관점에서 대답 에 의해 주어진 blid , 나는 당신이 지금까지 한 일을 파괴하지 않고이를 중개 반응성 해당 솔루션 및 필수 프로그램을 제안한다.
분명히 누군가 특정 데이터 구조를 생성하기위한 명령형 프로그래밍에 익숙하다면 그가 좋아하는 것을 자유롭게 할 수 있지만 각도 환경을 사용하기로 결정했다면 그것이 제공하는 모든 기회를 알아야합니다!
어쨌든 ... 이것은 서비스입니다.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AppConfig } from 'src/app/app.config';
import { forkJoin, Observable } from 'rxjs';
import { shareReplay, map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class BibliographyParserService {
private editionUrls = AppConfig.evtSettings.files.editionUrls || [];
private bibliographicCitations$: Observable<BibliographicCitation[]>;
constructor(
private http: HttpClient,
) {
const parser = new DOMParser();
const bibliographicCitations: Array<BibliographicCitation> = [];
this.bibliographicCitations$ = forkJoin(this.getHttpCallsOBSStream()).pipe( //use pipe...
map(responses => { //...and map
responses.forEach(response => {
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 (!bibliographicCitations.includes(interfacedCitation)) { bibliographicCitations.push(interfacedCitation); }
} else {
const interfacedCitation: BibliographicCitation = {
authors: citation.getElementsByTagName('author'),
title: String(citation.getElementsByTagName('title')[0]).replace(/\s+/g, ' '),
date: citation.getElementsByTagName('date')[0],
};
if (!bibliographicCitations.includes(interfacedCitation)) { bibliographicCitations.push(interfacedCitation); }
}
});
});
return bibliographicCitations; //This is the core!!!
}),
shareReplay(1)
);
}
private getHttpCallsOBSStream() {
return this.editionUrls.map((path) => this.http.get(path, { responseType: 'text'}));
}
public getBibliographicCitations(): Observable<Array<BibliographicCitation>> {
return this.bibliographicCitations$;
}
}
export interface BibliographicCitation {
authors?: HTMLCollectionOf<Element>;
title: string;
date?: Element;
}
다음은 구성 요소에서 수행 할 작업의 예입니다.
constructor(
public bps: BibliographyParserService,
) {
this.bps.getBibliographicCitations().subscribe(response => {
response.forEach(cit => {
console.log(cit);
});
});
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다