2016-06-04 8 views
32

मैं ऐसे अनुप्रयोग पर काम कर रहा हूं जो एनआरएक्सएक्स/स्टोर 1.5 का उपयोग थंक मिडलवेयर के साथ कर रहा है और मैं एनजीआरएक्स/स्टोर 2.0 और एनजीआरएक्स/प्रभावों में जाने की कोशिश कर रहा हूं। मेरे पास कई संबंधित कार्यों और/या प्रभावों को संभालने के तरीके के संबंध में कुछ प्रश्न हैं।एनजीआरएक्स/प्रभावों के साथ कई संबंधित संचालन/प्रभाव/क्रियाएं कैसे करें

मुझे एहसास है कि थंक्स बनाम प्रभावों के लिए "मानसिकता" अलग है और मैं अंतर के चारों ओर अपना सिर पाने की कोशिश कर रहा हूं। मैंने उपलब्ध उदाहरण ऐप्स को देखा है, और जो कुछ भी मैं कोशिश कर रहा हूं उसे फिट करने के लिए कुछ भी नहीं मिला है, इसलिए शायद मैं अभी भी पूरी तरह गलत हूं।

@Effect login$: any = this.updates$ 
    .whenAction(LoginActions.LOGIN) 
    .map(toPayload) 
    .switchMap(payload => 
     this.loginService.login(payload.user, payload.password) 
      .map(result => this.actions.loginSuccess(value)) 
      .catch((error) => Observable.of(this.loginError(error))) 
)); 

यह देखते हुए कि प्रारंभिक पक्ष प्रभाव, क्या "सही होगा:

परिदृश्य 1

यहाँ एक पक्ष प्रभाव एक लॉगिन के लिए सर्वर के लिए अनुरोध करने वाले को संभालने के लिए है सफल लॉगिन पर "होम" स्क्रीन पर नेविगेशन ट्रिगर करने के लिए "या" सुझाया गया "तरीका? इसे क्रियाओं या संचालन के अनुक्रम को आसानी से ट्रिगर करने के लिए भी सामान्यीकृत किया जा सकता है।

कुछ विकल्प पर विचार किया है:

(क) एक और प्रभाव लॉगिन सफलता से शुरू हो रहा है कि एक बाद कार्रवाई आग नेविगेशन गति प्रदान करने के?

@Effect navigateHome$: any = this.updates$ 
    .whenAction(LoginActions.LOGIN_SUCCEEDED) 
    .mapTo(this.actions.navigateHome()); 

(बी) लॉगिन सफलता से ट्रिगर एक और प्रभाव, जो केवल नेविगेशन ऑपरेशन करता है?

@Effect navigateHome$: any = this.updates$ 
    .whenAction(LoginActions.LOGIN_SUCCEEDED) 
    .do(this.navigateHome()) 
    .filter(() => false); 

(सी) शुरुआती लॉगिन प्रभाव से उत्सर्जित लोगों को अतिरिक्त कार्रवाई का सामना करना? (नमूना स्पष्ट रूप से बिल्कुल सही नहीं है, लेकिन विचार देता है)

@Effect login$: any = this.updates$ 
    .whenAction(LoginActions.LOGIN) 
    .map(toPayload) 
    .switchMap(password => Observable.concat(
     this.loginService.login(passcode) 
      .map(result => this.actions.loginSuccess(value)) 
      .catch((error) => Observable.of(this.loginError(error))), 
     Observable.of(this.actions.navigateHome()) 
    )); 

(डी) अन्य?

परिदृश्य 2

एक मामले में जहां अनुरोधों का एक नंबर अनुक्रम में किए जाने की जरूरत है पर विचार करें, और के रूप में प्रत्येक अनुरोध शुरू होता है हम उस प्रतिक्रिया उपयोगकर्ता के लिए प्रदान किया जा सकता है ताकि "स्थिति" अपडेट करना चाहते हैं।

उन पंक्तियों के साथ कुछ करने के लिए एक thunk का उदाहरण:

multiphaseAction() { 
    return (dispatch) => { 
     dispatch(this.actions.updateStatus('Executing phase 1'); 
     this.request1() 
      .flatMap(result => { 
       dispatch(this.actions.updateStatus('Executing phase 2'); 
       return this.request2(); 
      }) 
      .flatMap(result => { 
       dispatch(this.actions.updateStatus('Executing phase 3'); 
       return this.request3(); 
      }) 
      ... 
    } 
} 

फिर, क्या होगा "सही" या "सुझाव" जिस तरह से प्रभाव दृष्टिकोण का उपयोग कर में इस बारे में जाने के लिए?

यह एक मैं और अधिक, पर अटक वास्तव में नहीं यकीन है कि क्या कुछ .do(this.store.dispatch(this.actions.updateStatus(...)) किसी भी तरह जोड़ने के अलावा अन्य किया जा सकता है हूँ ...

+0

परिदृश्य 2 एक सादे पुराने सेवा वर्ग के लिए एक बहुत अच्छी मामला है। –

उत्तर

17

नेविगेशन परिदृश्य के लिए इसका जवाब आपके ख जवाब

@Effect navigateHome$: any = this.updates$ 
    .whenAction(LoginActions.LOGIN_SUCCEEDED) 
    .do(this.router.navigate('/home')) 
    .ignoreElements(); 

स्पष्टीकरण है: आप LOGIN_SUCCESS पर प्रतिक्रिया है, और क्योंकि रूटर किसी नए कार्य के वापस नहीं करता है, हम के प्रसार को रोकने के लिए की जरूरत है धारा, जो हम सब कुछ फ़िल्टर करके करते हैं।

आप फ़िल्टर करना भूल जाते हैं, रूटर अपरिभाषित, जो बारी में कम करने के लिए नेतृत्व करेंगे एक अपरिभाषित मूल्य है, जो आम तौर पर एक नल पॉइंटर में जो परिणाम कम करने के लिए देता है जब यह कार्रवाई की type पढ़ने का प्रयास

इसे हल करने का एक और तरीका https://github.com/ngrx/router-store

अपने ऐप पर राउटर-स्टोर को जोड़ने के तरीके पर दस्तावेज़ देखें।

वही प्रभाव अब इस तरह दिखेगा।

import { go } from '@ngrx/router-store'; 

@Effect navigateHome$: any = this.updates$ 
    .whenAction(LoginActions.LOGIN_SUCCEEDED) 
    .map(() => go(['/home'])); 

go कार्रवाई एक रूटर कार्रवाई कि रूटर कम करने ले सकते हैं और एक मार्ग परिवर्तन को गति प्रदान करेगा भेजेंगे।

+0

राउटर इंजेक्शन करते समय: प्रभाव वर्ग में राउटर, एक चक्रीय निर्भरता त्रुटि फेंक दी जाती है। क्या आपने इसे अपने ऐप में आजमाया था? –

+0

ऊपर दिखाए गए अनुसार, इसके बजाय राउटर-स्टोर का उपयोग करें। इस तरह आपको अपने प्रभाव में राउटर इंजेक्शन नहीं होना चाहिए। –

+0

जिज्ञासा से बाहर, प्रभाव सजावट समारोह में '{प्रेषण: झूठी} 'पास करने पर' ignoreElements' का उपयोग करने का कोई फायदा है? उदाहरण के लिए: '@Effect ({प्रेषण: झूठा}) प्रभाव WichDoesNotReturnAnAction $ ' –

-1
मैं भी इस चीज सीख रहा हूँ

क्या होगा अगर आप श्रृंखला में पहला होने पर रेड्यूसर को भेज दिया जाए?

कुछ इस तरह:

const myReducer = (state,action:Action) => { 
switch action.type { 
case : "my_first_step" : runfirststep(action.payload); 
case : "my_second_step": runsecondstep(action.payload); 
.... 

function runfirststep(data) { 
... 
//bunch of stuff to do, 
//update something to display 
store.dispatch('my_second_step'); 
} 

आदि

एनजीआरएक्स उदाहरण प्रभाव फ़ाइल में करता है। जब जोड़ें या अपडेट करें, तो वे UPDATE_COMPLETE या कुछ समान रूप से कॉल करते हैं ताकि कुछ अधिसूचना की जा सके।

मैं धीरे-धीरे समझ रहा हूं कि रेड्यूसर एक जटिल जटिल ऐप में कितना बड़ा होगा।

+1

एक reducer में स्टोर तक कोई पहुंच नहीं है। याद रखें कि reducer शुद्ध-कार्य हैं, यानी, कोई दुष्प्रभाव नहीं है। वास्तव में –

+0

। उदाहरण ऐप में एक प्रेषण LOAD_COLLECTION रेड्यूसर में 'प्रतीक्षा' करने के लिए एस स्थिति सेट करता है। प्रभाव राज्य परिवर्तन और प्रेषण का पता लगाता है, क्वेरी के लिए दूरस्थ कॉल करता है। कॉलबैक में यह क्वेरी पेलोड के साथ LOAD_COLLECTION_COMPLETE भेजता है, जो प्रतीक्षा करता है और राज्य को डेटा प्रदान करता है। –

0

परिदृश्य 1

विकल्प एक & बी दोनों जाना मुझे लगता है कि अच्छे हैं, लेकिन शायद विकल्प एक बस नेविगेशन के लिए बहुत ज्यादा एक सा है! यदि आप नेविगेशन को इस दुष्प्रभाव के हिस्से के रूप में देखते हैं तो आप सीधे अपने LoginActions.LOGIN में राउटर का भी उपयोग कर सकते हैं।

परिदृश्य 2

@Effects अप चेनिंग के साथ गलत कुछ भी नहीं है। एक क्रिया (SET_1_REQUEST) को प्रेषित करें जो आपके प्रभाव को ट्रिगर करता है ए प्रभाव ए एक क्रिया (SET_1_SUCCESS) देता है जो आपके रेड्यूसर द्वारा उठाया जाता है (अब आप उस स्थिति को उपयोगकर्ता को प्रदर्शित कर सकते हैं) और इसे प्रभाव से उठाया जाता है। बी

आशा है कि यह समझ में आता है।

2

परिदृश्य 1

पर विचार किया जाए या नहीं navigateHome राज्य बदलना चाहिए। साथ ही, यह navigateHome एक ही चीज़ को प्राप्त करने के लिए अन्य स्थानों से कार्रवाई भेजी जाती है या नहीं। यदि ऐसा है, तो एक कार्रवाई वापस करने का रास्ता है। इसलिए, विकल्प ए

कुछ मामलों में विकल्प बी अधिक समझ में आ सकता है। यदि navigateHome केवल मार्ग बदलता है, तो यह विचार करने लायक हो सकता है।

साइड-नोट: filter(() => false) के बजाय आप ignoreElements का उपयोग कर सकते हैं।

परिदृश्य 2

मैं यहाँ एकाधिक प्रभाव में अपने कार्यों चेनिंग और हर कार्रवाई के लिए कम करने में राज्य को संशोधित करके प्रतिक्रिया देने का सुझाव देते हैं।

उदाहरण के लिए:

@Effect() trigger$: Observable<Action> = this.updates$ 
    .whenAction(Actions.TRIGGER) 
    .do(() => console.log("start doing something here")) 
    .mapTo(Actions.PHASE1); 

@Effect() phase1$: Observable<Action> = this.updates$ 
    .whenAction(Actions.PHASE1) 
    .do(() => console.log("phase 1")) 
    .mapTo(Actions.PHASE2); 

@Effect() phase2$: Observable<Action> = this.updates$ 
    .whenAction(Actions.PHASE2) 
    .do(() => console.log("phase 2")) 
    .ignoreElements(); 

और राज्य को संशोधित करके प्रतिक्रिया दे:

function reducer(state = initialState, action: Action): SomeState { 
    switch (action.type) { 
     case Actions.TRIGGER: { 
      return Object.assign({}, state, { 
       triggered: true 
      }); 
     } 
     case Actions.PHASE1: { 
      return Object.assign({}, state, { 
       phase1: true 
      }); 
     } 
     case Actions.PHASE2: { 
      return Object.assign({}, state, { 
       phase1: false, 
       phase2: true 
      }); 
     } 
     // ... 
    } 
} 
संबंधित मुद्दे