2016-09-07 5 views
2

MobXを使用しているときに遅延ロードプロパティを使用する現在の慣用方法は何ですか?mobxで遅延ロードするための慣習的な方法

私はこれを数日間苦労してきましたが、厳密なモードが問題になって以来、良い例は見つかりませんでした。厳密モードの考え方が気に入っていますが、レイジーローディングがそれと矛盾していると思っています(アクセスしている、またはプロパティが存在していない場合はデータロードの副作用を引き起こすプロパティを観察する必要があります)。

これは私の質問の要点ですが、ここでどのように読んでいるのか見ることができます。コンポーネントは、ルートのparamsからフィルタ値を取得 - componentWillMount

  1. componentWillMount & componentWillReceiveProps:

    私の現在の設定の基礎を(コードのトンを掲示せず):

    は成分1(リストビュー)を反応させ(反応ルータ)に保存し、それを観測可能なオブジェクトとしてListViewに保存し、それに基づいてストアに「プロポーザル」をフェッチするように指示します

  2. Store.fetchProposalsはその要求がすでに行われているかどうかを確認します2つの同一のフィルタが同じレスポンスオブジェクトを返すように、フィルタオブジェクトをシリアライズすることによってキーが生成されます)。リクエストが完了したか、エラーが発生したかを示す情報を含む観測可能なレスポンスオブジェクトを返す必要があるかどうかをリクエストします。
    1. ListViewは、観察可能なレスポンスオブジェクトをプロパティとして保存し、ロードインジケータまたはエラーインジケータを表示できます。
    2. リストビューは、
    3. Store.getProposalsをフェッチするために使用される同一のフィルタオブジェクトを使用してStore.getProposalsを呼び出し、計算プロパティがフィルタオブジェクトを受け取り変圧器である有し、ObservableMap(proposal.id上のキー)からのすべての提案を取得しますこれはすべてが順調に動作しているように見えます

フィルタオブジェクトを使用してリストをフィルタリングし、(何もなしの提案がまだロードされていない場合を含め、フィルタに一致しない場合は、空の)提案[]を返します。

問題は、プロポーザルにはclientとclientIdのプロパティがあることです。 Proposal.clientIdは、プロポーザルで読み込まれた文字列です。私はクライアントが実際にアクセスされるまで待って、ストアからサーバーからフェッチするようにストアに指示します(まだストアにないと仮定して)。この場合、ListViewはクライアント名を表示するため、プロポーザルの直後にロードする必要があります。

私が一番近かったのは、プロポーザルのコンストラクタリストに自動実行を設定していますが、その一部は私がインデントしている場所に反応しません。

@observable private clientId: string = ''; 
@observable private clientFilter: IClientFilter = null; 
@observable client: Client = null; 

constructor(sourceJson?: any) { 
    super(sourceJson); 
    if (sourceJson) { 
     this.mapFromJson(sourceJson); 
    } 
    //this one works. I'm turning the clientId string into an object for the getClients transformer 
    autorun(() => { runInAction(() => { this.clientFilter = { id: this.clientId }; }) }); 
    autorun(() => { 
     runInAction(() => { 
      if (this.clientId && this.clientFilter) { 
       const clients = DataStore.getClients(this.clientFilter); 
       const response = DataStore.fetchClients(this.clientFilter); 
       if (response.finishedTime !== null && !response.hasErrors) { 
        this.client = clients[0] || null; 
        console.log('This is never called, but I should see a client here: %o', DataStore.getClients(this.clientFilter)); 
       } 
      } 
     }) 
    }); 
} 

レスポンスオブジェクトが観測可能である:(関連するセクションに切り捨て)

export class QueryRequest<T extends PersistentItem | Enum> { 
    @observable startTime: Date = new Date(); 
    @observable finishedTime: Date = null; 
    @observable errors: (string | Error)[] = []; 
    @observable items: T[] = []; 
    @computed get hasErrors() { return this.errors.length > 0; } 
    @observable usedCache: boolean = false; 
} 

私は、システムを戦っている感じを取得し、コンストラクタで自動実行を設定してい」doesnのとにかく理想的ですね。誰でもこのパターンを妥当な方法で解決しますか?セットアップが狂ったように見えたら、私は全面的な提案をすることができます。


EDIT 1:明確にするために@Mobxを削除しました。


EDIT 2:私の状況を再評価しようとすると は、I(再び)は私のニーズを、スイートもlazyObservable機能を持っている優れたLIB mobx-utilsを見つけました。現在、このように見ている:これは働いている

client = lazyObservable((sink) => { 
    autorun('lazy fetching client',() => { 
     if (this.clientFilter && this.clientFilter.id) { 
      const request = DataStore.fetchClients(this.clientFilter); 
      if (request.finishedTime !== null && !request.hasErrors) { 
       sink(request.items[0]); 
      } 
     } 
    }) 
}, null); 

このオブジェクトのclientId/clientFilterプロパティ(このオブジェクトが新しいクライアントに割り当てられている場合は、lazyObservableを更新する必要があります)に基づいて更新するには、そこに自動実行が必要だと思います。私は怠け者のプロパティのための少しの定型文に気にしませんが、私は間違いなくそこに提案を開いています。

これが終了する場合は、私の観察可能なリクエストオブジェクトではなく、同じlibのfromPromiseも見ていきます。私が陳腐化をチェックするための開始時間を追跡しているので、わからない。私は私のプロジェクトに異なるアプローチを使用してきたと私は別のNPMパッケージにそれを抽出し、他の誰かがそれに遭遇していない場合に、ここにリンク:)

+0

必要に応じて、より多くのコードを投稿してもらい、テキストの壁を短くしようとしています。 – Jakke

+0

'@ Mobx.'という接頭辞が付いているのはなぜですか?あなたは非構造化インポートを実行できません。 –

+1

データをストアレイヤーに保管したり、約束したり、MobXにリポジトリクラスを持たせてサーバーに触れることができます。一般的に、私はオートランがコードのより深い問題を示すのを発見しました。 –

答えて

2

https://github.com/mdebbar/mobx-cache

は、ここでは簡単な例です:

:我々はセットアップ clientCacheに必要な、そして、

@observer 
class ClientView extends React.Component { 
    render() { 
    const entry = clientCache.get(this.props.clientId) 

    if (entry.status !== 'success') { 
     // Return some kind of loading indicator here. 
     return <div>Still loading client...</div> 
    } 

    const clientInfo = entry.value 
    // Now you can render your UI based on clientInfo. 
    return (
     <div> 
     <h2>{clientInfo.name}</h2> 
     </div> 
    ) 
    } 
} 

まず、クライアント情報を表示するコンポーネントを反応させるの必要210

import MobxCache from "mobx-cache"; 

function fetchClient(id) { 
    // Use any fetching mechanism you like. Just make sure to return a promise. 
} 

const clientCache = new MobxCache(fetchClient) 

これだけです。必要なときにMobxCacheによって自動的にfetchClient(id)が呼び出され、データがキャッシュされます。

+0

それはあなたがそこに持っている素晴らしいライブラリです、良い仕事! – Jakke

+0

ありがとう@ジャック!図書館はまだ早い段階で開発されており、私は感謝しています。 –

関連する問題