0
나는 두 개의 구성 요소 사이의 통신에 Rxjs에서 Observable 인 및 주제를 사용하고

에 대한 Observables은 사용 방법, 여기에 서비스 일부입니다구성 요소 간 통신

import { 
 
    Injectable, 
 
    EventEmitter, 
 
    Output 
 
} from '@angular/core'; 
 
import { 
 
    HttpClientModule, 
 
    HttpClient 
 
} from '@angular/common/http'; 
 

 
import { 
 
    Observable 
 
} from 'rxjs/Rx'; 
 
import 'rxjs/add/operator/map'; 
 
import 'rxjs/add/operator/catch'; 
 
import { 
 
    Subject 
 
} from 'rxjs/Subject'; 
 

 

 
import { 
 
    AppConstants 
 
} from './../config/constants'; 
 

 
@Injectable() 
 

 
export class GlobalService { 
 
    private subject = new Subject <any>(); 
 
    @Output() LoggedIn: EventEmitter <any> = new EventEmitter(); 
 
    mfaData: any; 
 
    constructor(private http: HttpClient) { 
 

 
    } 
 

 
    validateCreds(postData, institutionId, customerId) { 
 
    return this.http.post(AppConstants.baseUrl + AppConstants.serverRoutes.validateCreds + institutionId + '/' + customerId, postData) 
 
     .subscribe(response => { 
 
     console.log(response); 
 
     if (response['status'] == 203) { 
 
      this.mfaData = response['body'].questions; 
 
      if (this.mfaData[0].choices || this.mfaData[0].imageChoices) { 
 
      console.log('hey there'); 
 
      this.subject.next({ 
 
       mfaData: JSON.stringify(this.mfaData) 
 
      }); 
 
      
 
      } 
 
     } 
 
     }) 
 
    } 
 

 

 
    
 

 
    refreshHeaders(): Observable <any> { 
 
    return this.subject.asObservable(); 
 
    } 
 

 

 

 

 

 
}
내가로부터 가입자를 호출하고 다른 구성 요소의 생성자가의 단편이다

import { 
 
    Subscription 
 
} from 'rxjs/Subscription'; 
 
import { 
 
    GlobalService 
 
} from '../../../providers/global.serivce'; 
 

 
export class MfaChallengeComponent implements OnInit { 
 
    subscription: Subscription; 
 
    constructor(private activatedRoute: ActivatedRoute, private bankService: BanksService, private globalService: GlobalService) { 
 
    this.subscription = this.globalService.refreshHeaders().subscribe(message => { 
 
     console.log(message); 
 
    }); 
 
    } 
 
}

하지만 백엔드에서 데이터를 받으면 피사체의 다음 메서드를 호출하고 다른 구성 요소의 생성자에서 다시 호출합니다. 작동하는 예제를 본 반면 작동하지 않습니다. 이 서비스는 전 세계적으로 주입되었습니다.

+0

아래에 정말 좋은 설명이 있습니다. 나는 각도 관점에서 단지 그것을 추가 할 것이다.'생성자 (constructor) '는 서비스를 호출하기에 아주 좋은 곳이다. 'ngOnInit()'는 보통 상황이 대신 일어나는 곳입니다. –

답변

4

RxJS의 핵심 개념을 오해하고 있습니다. RxJS에서 주체는 뜨거운 관측 가능 항목입니다. 뜨거운 관측 대상자는 아무도 듣지 않던간에 이벤트를 내 보냅니다. (자세한 내용은이 문서를 확인하십시오 https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html).

서비스에서 백엔드 호출을 수행한다고 가정 해 봅니다. 여기에서 호출을 통해 결과를 파이프 처리합니다. 나중에 코드에서 구성 요소가 시작되고 생성자가 실행되고 주제를 듣기 시작합니다. 피사체를 통과 한 이벤트는 이미 불행하게도 지나갔습니다.

이 문제를 해결하려면 ReplaySubject (1)로 제목을 변경할 수 있습니다. 내가 잘못 본 것이 아니라면 문제가 해결 될 것입니다.

그러나 코드에 다른 문제가 있습니다. 결과를 피사체로 파이프하는 사실은 여기서는 불필요합니다. 귀하의 코드를 살펴 본다면 백엔드 호출을 한 번 수행 한 다음 결과를 캐시하려고한다고 생각합니다. 이에 대한 구체적인 연산자는 shareReplay입니다. 코드는 다음과 같이 것을 사용 :

export class GlobalService { 
 
    cachedObservable$; 
 
    @Output() LoggedIn: EventEmitter <any> = new EventEmitter(); 
 
    mfaData: any; 
 
    constructor(private http: HttpClient) { 
 
    } 
 

 
    validateCreds(postData, institutionId, customerId) { 
 
    this.cachedObservable$ = this.http.post(AppConstants.baseUrl + AppConstants.serverRoutes.validateCreds + institutionId + '/' + customerId, postData) 
 
     .map(response => { 
 
     if (response['status'] == 203) { 
 
      this.mfaData = response['body'].questions; 
 
      if (this.mfaData[0].choices || this.mfaData[0].imageChoices) { 
 
      return { 
 
       mfaData: JSON.stringify(this.mfaData) 
 
      }; 
 
      } 
 
     } 
 
     }) 
 
     .shareReplay(1); 
 
    } 
 

 
    refreshHeaders(): Observable <any> { 
 
    return this.cachedObservable$; 
 
    } 
 
}

당신은 한 번 실행되고 결과가 이후에 캐시 할 것이라는 관측을 만들 수 있습니다. 당신은 가능한 한 많은 서비스와 주제에 서브 스크립 션을 사용하지 않도록 노력해야합니다. shareReplay에 대해 자세히 알아 보려면 RxJS의 멀티 캐스팅 사업자에 대한 블로그 포스트를 확인하십시오. https://blog.kwintenp.com/multicasting-operators-in-rxjs

+0

이봐 요, 몇 가지 변경 사항이있는 코드를 시도했지만 작동하기 시작했습니다. 그러나 여기서 다시 발생하는 문제는 주제 다음 메소드를 통해 데이터를 전달할 때 구독이 호출되고 이벤트를 수신한다는 것입니다. 그러나 리스너 함수가있는 동일한 구성 요소가 호출 될 때 데이터를 가져 오지 않습니다. – Raghav