티스토리 뷰
라우터 관찰 가능 항목 (다른 답변에서 언급 했듯이 ) 은 BehaviorSubject
주제 이며 시퀀스에 초기 값이 푸시된다는 점에서 일반 RxJS Subject
또는 Angular 2 와 다릅니다 EventEmitter
(의 경우 빈 개체 queryParams
).
일반적으로 초기화 로직으로 구독하는 것이 바람직합니다.
초기 값은 skip
연산자 로 건너 뛸 수 있습니다 .
this._route.queryParams
.skip(1)
.subscribe(params => ...);
그러나이를 처리하는보다 자연스러운 방법은 모든 관련없는 매개 변수를 필터링하는 것입니다 (초기 값 params
이이 범주에 속함). 백엔드에 대한 불필요한 호출을 방지하기 위해 연산자로 중복 authorization_code
값을 필터링 할 수도 있습니다 distinctUntilChanged
.
this._route.queryParams
.filter(params => 'authorization_code' in params)
.map(params => params.authorization_code)
.distinctUntilChanged()
.subscribe(authCode => ...);
Angular 2는 제한된 양의 RxJS 연산자를 가져옵니다 (적어도 map
의 경우 @angular/router
). 전체 rxjs/Rx
번들을 사용하지 않는 경우 에서 사용중인 추가 연산자 ( filter
, distinctUntilChanged
) 를 가져와야 할 수 있습니다 import 'rxjs/add/operator/<operator_name>'
.
이를 극복하는 가장 좋은 방법은 라우터 이벤트를 구독하고 경로가 다음과 같은 navigated
상태 로 틱된 후에 만 쿼리 매개 변수를 처리하는 것 입니다.
public doSomethingWithQueryParams(): Observable<any> {
let observer: Observer<any>;
const observable = new Observable(obs => observer = obs);
this.router.events.subscribe(evt => {
// this is an injected Router instance
if (this.router.navigated) {
Observable.from(this.activatedRoute.queryParams)
// some more processing here
.subscribe(json => {
observer.next(json);
observer.complete();
});
}
});
return observable;
}
-------------------그것은 의도적으로 설계된 것 같습니다.
queryParams
는 IS BehaviorSubject은
문서 에서 볼 수 있듯이
주제의 변형 중 하나는 "현재 값"이라는 개념을 가진 BehaviorSubject입니다. 소비자에게 방출 된 최신 값을 저장하고 새로운 Observer가 구독 할 때마다 BehaviorSubject에서 "현재 값"을 즉시받습니다.
해결 방법 debounceTime
으로 다음과 같이 연산자를 사용할 수 있습니다 .
import 'rxjs/add/operator/debounceTime';
this._route.queryParams
.debounceTime(200)
.subscribe(params => {
console.log(params);
});
-------------------NavigationEnd 이벤트가 완료 될 때까지 기다린 다음 값을 가져 오거나 변경 사항을 구독 할 수 있습니다.
constructor(private router: Router, private route: ActivatedRoute) { }
public ngOnInit(): void {
console.log('INIT');
this.router.events
.subscribe((event) => {
if (event instanceof NavigationEnd) {
// Get a good value
let initialParams = this.route.snapshot.queryParams;
console.log(initialParams);
// or subscribe for more changes
this.route.queryParams.subscribe(params => {
console.log(params);
});
}
});
}
-------------------누군가가 이것에 대한 해결책을 찾고있는 경우를 대비하여 꽤 잘 작동하는 해결 방법을 찾았습니다. 내가 생각해 낸 솔루션 NavigationEnd
은 Router 인스턴스 의 이벤트 에 대해서만 구독을 수행하는 것 입니다.
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
this.router.events
.subscribe(e => {
if (e.constructor.name === 'NavigationEnd' && this.router.navigated) {
this.route.queryParams
.subscribe(params => {
// do something
})
.unsubscribe();
}
});
}
-------------------Location
클래스를 사용 하여 초기 URL을 가져오고, UrlSerializer
클래스를 구문 분석 UrlTree
하여 쿼리 매개 변수를 가져옵니다.
이 링크로 이동하면 https://dev-hubs.github.io/ReactiveXHub/#/operators/conditional/skipUntil
1) 복사이 코드를 코드 편집기에 붙여 넣습니다 .
/* since queryParams is a BehaviorSubject */
var queryParams = new Rx.BehaviorSubject();//this will AUTOMATICALLY alert 'undefined'
var subscription = queryParams.subscribe(
function (x) {
alert(x);
},
function (err) {
alert(err);
},
function () {
alert('Completed');
});
queryParams.onNext('yay');//this will cause to alert 'yay'
2) 실행 버튼 누르기
두 번 경고를 받게됩니다. 하나는 구독에서 직접, 두 번째는 마지막 줄의 bcz입니다.
현재 결과는 잘못된 것이 아닙니다. Rx의 'operators make thing'이라는 철학이 있습니다.이 의사 결정 트리를 조회하여 찾고있는 연산자를 볼 수 있습니다. http://reactivex.io/documentation/operators.html#tree 일반적으로 사용합니다. 스킵 (1)
-------------------ngAfterViewInit 메서드에 구독 코드를 입력하고,
ngAfterViewInit() {
this.route.queryParams.subscribe(params => {
debugger;
});
}
출처
https://stackoverflow.com/questions/39940166