2017-11-18 4 views
0

私の背景は.NET開発であり、WPFです。あなたがC#で認証されたアクションを呼びたいとき、これはあなたが大まかにしなければならないことです。ReduxでReduxに反応します。Observableの認証処理が完了するまで待ってから続行します。

var res = action(); 
if(res == Not authenticated) 
{ 
    var cred = await showDialog(); 
    action(cred); 
} 

かなり簡単なあなたは、ユーザーが認証情報を入力し、再び資格情報を使用してアクションを呼び出すことができますショーダイアログウィンドウを認証されない場合は、アクションを呼び出します。

私はepicsでreduxで同じ機能を実装しようとしています。

export const pullCurrentBranchEpic = (action$: ActionsObservable<Action>, store: Store<ApplicationState>) => 
    action$ 
    .filter(actions.pullCurrentBranch.started.match) 
    .mergeMap(action => Observable.merge(
     Observable.of(repoActions.authenticate.started({})), 
     waitForActions(action$, repoActions.authenticate.done) 
        .mergeMap(async _=>{ 
        const repository = await getCurrentRepository(store.getState()); 
        await pullCurrentBranch(repository); 
        }) 
        .map(_=>actions.pullCurrentBranch.done({params:{},result:{}})) 
        .race(
        action$.ofType(repoActions.authenticate.failed.type) 
         .map(() => actions.pullCurrentBranch.failed({error:"User not authenticated",params:{}})) 
         .take(1)) 
    )); 
export const waitForActions = (action$, ...reduxActions) => { 
    const actionTypes = reduxActions.map(x => x.type); 
    const obs = actionTypes.map(type => action$.ofType(type).take(1)); 
    return Observable.forkJoin(obs); 
}; 

基本的叙事詩がアクションを処理します(それは、このコードを倍増するため、ユーザーが認証するかどう私もチェックしていない)とアクションが別のアクションを実行します - authenticate.startedで状態を変更しますウィンドウを開くための減速機、ユーザーは彼の資格情報を入力することができ、彼がそれを行うとき、それはauthenticate.doneアクションを呼び出すでしょう。それが終わると、叙事詩は、それが終わったときに別の行動を起こすような行動をとる約束を続けます。私は何か間違っているのですか?そのような単純なことのために複雑すぎるのではないか?私はそれがreduxとの問題だとは思わないが、むしろredux観察し、叙事詩。

答えて

2

これはお客様のニーズに合っている可能性があります。重要なことは、問題を複数の叙事詩に分解することです。

const startAuthEpic = action$ => action$ 
    .filter(action.pullCurrentBranch.start.match) 
    .map(action => repoActions.authenticate.started({}); 

const authDoneEpic = (action$, store) => action$ 
    .ofType(repoActions.authenticate.done.type) 
    .mergeMap(() => { 
    const repo = getCurrentRepository(store.getState()); 
    return Observable.fromPromise(pullCurrentBranch(repo)) 
     .map(() => actions.pullCurrentBranch.done({ ... })) 
     .catch(error => Observable.of(actions.pullCurrentBranch.failed({ ... }))) 
    }); 

より認証されたアクションを含む複数の方法、1ビーイングがあります

// each new authenticated action would need to fulfill the below contract 
const authenticatedActions = [ 
    { 
    action: 'pull', 
    match: action.pullCurrentBranch.start.match, 
    call: store => { 
     const repo = getCurrentRepository(store.getState()); 
     return pullCurrentBranch(repo); 
    }, 
    onOk:() => actions.pullCurrentBranch.done({}), 
    onError:() => actions.pullCurrentBranch.failed({}) 
    }, 
    { 
    action: 'push', 
    match: action.pushCurrentBranch.start.match, 
    call: store => { 
     const repo = getCurrentRepository(store.getState()); 
     return pushCurrentBranch(repo); 
    }, 
    onOk:() => actions.pushCurrentBranch.done({}), 
    onError:() => actions.pushCurrentBranch.failed({}) 
    } 
]; 

const startAuthEpic = action$ => action$ 
    .map(action => ({ action, matched: authenticatedActions.find(a => a.match(action)) })) 
    .filter(wrapped => wrapped.matched) 
    .map(wrapped => repoActions.authenticate.started({ whenAuthenticated: wrapped.matched })); 

const authDoneEpic = (action$, store) => action$ 
    .ofType(repoActions.authenticated.done.type) 
    .pluck('whenAuthenticated') 
    .mergeMap(action => { 
    const { call, onOk, onError } = action; 
    return Observable.fromPromise(call(store)) 
     .map(onOk) 
     .catch(err => Observable.of(onError(err))) 
    }); 

あなただけauthenticate.doneアクションにwhenAuthenticatedプロパティに沿って通過しなければなりません。

+0

いいですね。しかし、認証はプルだけでなく、プッシュするためにも行われると想像することができます。あなたのソリューションをどのように拡張して、両方で動作させるのですか? AuthDoneEpicは、彼がどのような行動をとるべきか、失敗した場合の対処方法に関する情報を持っている必要があります。あなたはauthenticate.doneアクションペイロードにそれを格納しますか? – MistyK

+0

はい、次に実行する認証されたアクションを 'authenticate.done'ペイロードに含める必要があります。私はこれを行う一つの方法を示すために私の答えを編集しました。 –

+0

開始から終了までの間にペイロードを保管しなければならないということですか? – MistyK

関連する問題