2017-03-06 31 views
1

저는 RxJS (5.1.1 사용)에 익숙하며 angle-redux/store를 사용하여 Angular 2 applciation에서이를 이해하려고합니다.각도 2 RxJS 필터에서 새로운 관측 가능

나는 응용 프로그램에서 내 국가의 다른 부분을 얻으려는 상점을 만들고 있습니다.

내 상태 :

export interface IAppState extends IRootState{ 
    theme: Theme; 
    config: IConfig; 
    mainSubTitle: string; 
    appParts: AppPart[]; 
} 

선택 :

@select(state => state.app.appParts) appParts$: Observable<AppPart>; 

지금, 나는 '이제

, 나는 loaded 속성이 true로 설정 한 AppParts을 얻으려고 이 관찰 가능 필터 된 배열을 얻으려는 시도 :

loadedAppParts = []; 

ngOnInit() { 
    this.appParts$.filter(a => a.loaded).subscribe(a => { console.log(a); this.loadedAppParts.push(a); }); 
} 

그러나 빈 배열이 반환됩니다. 나는 'loadedAppParts'도 가능한 경우를 얻기 위해 비동기 파이프를 사용할 수 있도록하고 싶습니다, 그래서 나는 또한 다음과 같은 일을 시도했다 : 그래서

loadedAppParts: Observable<AppPart> = new Observable<AppPart>(); 
ngOnInit() { 
    this.loadedAppParts = this.appParts$.filter(a => a.loaded); 
} 

, 어떻게 얻을 수 필터링 된 배열 또는 관찰을 내 관찰 가능한 국가 에서요?

export interface IRootState { }; 

내 초기 상태 :

export const INITIAL_STATE: IAppState = { 
    theme: THEMES.LightGreyBlue, 
    config: <IConfig>{ 
    data: { 
     apiUrl: '' 
    }, 
    general: { 
     appName: 'Default name', 
     appShortName: 'default' 
    } 
    }, 
    mainSubTitle: 'Default', 
    appParts: [new AppPart('core', true)] 
}; 

그리고 (배열 예를 들어) 디버그에 JSON을 표시하는 템플릿 부분 :

내 Rootstate을 추가 잊으 {{ appParts$ | async | json }} {{ loadedAppParts | json }}

Observable :을 사용할 때{{ appParts$ | async | json }} {{ loadedAppParts | async | json }}

이 반환 [ { "name": "core", "loaded": true } ] null

+0

템플릿 부분도 표시 할 수 있습니까? 이 오류는 서로 참조하는 두 개의 객체를 JSON으로 변환하려고 할 때 발생합니다. JSON은 사용자가 원하는 것으로 생각하지 않습니다. 배열을 사용할 때 – martin

+0

: {{appParts $ | 비동기 | json}} {{loadedAppParts | json}}; Observable을 사용할 때 : {{appParts $ | 비동기 | json}} {{loadedAppParts | 비동기 | json}}; 마지막 출력은 [{ "name": "core", "loaded": true}] null – AppSum

+0

출력에서'appParts $'가'AppPart' 객체의 배열을 내보내는 것처럼 보이기 때문에 정확한 타입은'Observable '. 'this.loadedAppParts = this.appParts $ .mergeAll(). filter (a => a.loaded);로 배출량을 평탄하게하려고한다면'도움이 되나요? – martin

답변

2

json으로 출력에서 ​​다음과 같이 보이는 볼 수 있습니다

[ { "name": "core", "loaded": true } ] null 

그래서 appParts$ 사실 오브젝트 (Observable<AppPart[]>을)의 배열을 방출에 그냥 객체를 대신 (Observable<AppPart>).

this.appParts$.filter(a => a.loaded)을 사용하면 .loaded 속성을 사용하여 Array 객체에없는 항목을 필터링하려고하므로 항상 비어 있습니다.

실제로 배열 내에있는 개체를 필터링하려고합니다. 즉, 배열을 단일 항목으로 병합해야합니다. 이에

[ { "name": "core", "loaded": true }, { "name": "core", "loaded": true }, { "name": "core", "loaded": true } ] 

: 다음 mergeAll() 운영자가 무엇을 할 수

{ "name": "core", "loaded": true } 
{ "name": "core", "loaded": true } 
{ "name": "core", "loaded": true } 

이것은 우리가이 설정하는 것을 의미합니다. 이 경우 mergeAll()을 사용하면 merge(array => Observable.from(array))을 사용하는 것과 같습니다.당신이 .filter(a => a.loaded) 함께 체인 때

this.appParts$.mergeAll().filter(a => a.loaded); 

은 이제 AppPart 개체를 필터링하고 있습니다.

async 필터를 사용하면 Observable을 구독하고 항상 의 마지막 항목 만 소스에서을 방출한다는 점에 유의하십시오.

다시 배열로 필터링 항목을 수집하는 toArray()를 사용할 수 있습니다

this.appParts$.mergeAll().filter(a => a.loaded).toArray(); 

이 한 가지 중요한 결과가 있습니다. toArray() 연산자는 Observable 소스가 완료된 후에 만 ​​출 력합니다 (단, 유스 케이스에서는 문제가 아닐 수도 있음).

또는 모든 항목을 수집하려는 경우 scan() 연산자를 사용하여 소스의 모든 방출시 컬렉션을 방출 할 수 있지만이 연산자는 여러보기 업데이트를 유발할 수 있습니다.

this.appParts$.mergeAll().filter(a => a.loaded).scan((acc, item) => { 
    acc.push(item); 
    return acc; 
}, []); 
+0

감사합니다. 나는이 코드로 해결하는 것 같았다. this.loadedAppParts = this.appParts $ .map (appParts => appParts.filter (a => a.loaded)); AppParts $와 마찬가지로 Observable 을 반환합니다. – AppSum

관련 문제