2016-09-19 12 views
16

मैं 2.x के लिएप्रभाव में राज्य के पेड़ की पहुंच कैसे प्राप्त करें? (@ Ngrx/प्रभाव 2.x)

1.x में 1.x से @ngrx/effects अद्यतन करने कर रहा हूँ मैं प्रभाव में राज्य वृक्ष का उपयोग कर सकते है: 2 में

constructor(private updates$: StateUpdates<AppState>) {} 

    @Effect() bar$ = this.updates$ 
    .whenAction(Actions.FOO) 
    .map(obj => obj.state.user.isCool) 
    .distinctUntilChanged() 
    .filter(x => x) 
    .map(() => ({ type: Actions.BAR })); 

अब .x, यह केवल मुझे कार्रवाई देता है। क्या राज्य के पेड़ तक पहुंचने का अभी भी कोई तरीका है? या मुझे इस तरह का उपयोग करने से बचना चाहिए क्योंकि यह एक अच्छा अभ्यास नहीं है?

constructor(private actions$: Actions) {} 

    @Effect() bar$ = this.actions$ 
    .ofType(ActionTypes.FOO) 
    .map((obj: any) => { 
     console.log(obj);    // here is action only 
     return obj.state.user.isCool // so it is wrong here 
    }) 
    .distinctUntilChanged() 
    .filter(x => x) 
    .map(() => ({ type: ActionTypes.BAR })); 

उत्तर

19

एक और तरीका .withLatestFrom(this.store) का उपयोग कर रहा है। तो पूरा कोड है:

constructor(
    private actions$: Actions, 
    private store: Store<AppState> 
) {} 

@Effect() bar$ = this.actions$ 
    .ofType(ActionTypes.FOO) 
    .withLatestFrom(this.store, (action, state) => state.user.isCool) 
    .distinctUntilChanged() 
    .filter(x => x) 
    .map(() => ({ type: ActionTypes.BAR })); 
+1

इसके अलावा, यदि आप 'this.store.select (fromRoot.getUserIsCool) का उपयोग करते हैं, तो आपको' specificUntilChanged() 'का उपयोग करने की ज़रूरत नहीं है ... सही? – Helzgate

+0

स्टोर को 'withLatestFrom'' पर पास करना 'टाइपरर: आपने एक अवैध ऑब्जेक्ट प्रदान किया जहां स्ट्रीम की अपेक्षा की गई थी। आप एक अवलोकन, वादा, ऐरे, या इटेबल प्रदान कर सकते हैं। हालांकि यह काम करता है। कोई विचार क्यों मुझे त्रुटि मिलती है? –

4

प्रभाव वर्ग गुण होने की आवश्यकता नहीं है; वे भी तरीके हो सकते हैं। जिसका अर्थ है कि आप एक स्टोर तक पहुंच सकते हैं जो कि कन्स्ट्रक्टर में इंजेक्शन दिया गया है।

इस जवाब लिखने के समय, संपत्ति घोषणाओं के अर्थ विज्ञान औरpublic/privateनिर्माता मापदंडों मेरे लिए स्पष्ट नहीं थे। यदि कन्स्ट्रक्टर के बाद गुण घोषित किए जाते हैं, तो वेpublic/privateसदस्यों को कन्स्ट्रक्टर पैरामीटर के माध्यम से घोषित कर सकते हैं - इसलिए आपको अपने प्रभावों को कार्यों के रूप में घोषित करने की आवश्यकता नहीं है।

इंजेक्शन दुकान के साथ

, आप राज्य पाने के लिए mergeMap जैसे किसी ऑपरेटर का उपयोग करें और अद्यतन आपके द्वारा प्राप्त के साथ गठबंधन करने के लिए सक्षम होना चाहिए:

@Effect() 
bar$(): Observable<Action> { 

    return this.actions$ 
    .ofType(ActionTypes.FOO) 
    .mergeMap((update) => this.store.first().map((state) => ({ state, update }))) 
    .map((both) => { 
     // Do whatever it is you need to do with both.update and both.state. 
     return both.update; 
    }) 
    .distinctUntilChanged() 
    .filter(x => x) 
    .map(() => ({ type: ActionTypes.BAR })); 
    } 
} 

चाहे या इस से नहीं कर अच्छा अभ्यास एक है राय की बात है, मुझे लगता है। राज्य को पढ़ना - आदर्श रूप से एक एनजीआरएक्स-स्टाइल चयनकर्ता लिखकर - उचित लगता है, लेकिन यह स्पष्ट होगा यदि किसी विशेष प्रभाव के लिए आपको आवश्यक सारी जानकारी उस क्रिया में शामिल की गई थी जिसमें वह सुन रहा था।

+0

मैंने अपना जवाब संपादित कर लिया है। मैंने जो लिखा है उसका परीक्षण किया - मेरे सिर के ऊपर से - और मेरा ऐप बेर्सक गया, क्योंकि 'गठबंधन' के परिणामस्वरूप राज्य अपडेट के चक्र में परिणाम हुआ। एक टिप्पणी फिर से जोड़ा: अच्छा अभ्यास भी। – cartant

+1

आपको बहुत बहुत धन्यवाद! आपकी पहली कोशिश सही दिशा पर है, 'withLatestFrom' –

+1

Yep में बदलने की आवश्यकता है, 'withLatestFrom' एक बेहतर समाधान है। – cartant

संबंधित मुद्दे