はい、リレーショナル データベースのように複数のストアで ID を使用するのが正しい方法です。
あなたの例では、楽観的に新しいカードを特定の列に配置したいとしましょう。また、カードは 1 つの列 (1 つの列から多くのカード) にのみ配置できます。
CardStore のカードは次のようになります。
_cards: {
'CARD_1': {
id: 'CARD_1',
columnID: 'COLUMN_3',
title: 'Go to sleep',
text: 'Be healthy and go to sleep on time.',
},
'CARD_2': {
id: 'CARD_2',
columnID: 'COLUMN_3',
title: 'Eat green vegetables',
text: 'They taste better with onions.',
},
}
ID でカードを参照できることに注意してください。また、オブジェクト内で ID を取得することもできます。これによりgetCard(id)
、ビューレイヤー内の特定のカードの ID を取得したり、取得したりすることができます。したがってdeleteCard(id)
、ビュー内の ID を知っているため、アクションに応答して呼び出されるメソッドを持つことができます。
カード ストア内にはgetCardsByColumn(columnID)
、カード オブジェクトの単純なマップである があり、これにより、列の内容をレンダリングするために使用できるカードの配列が生成されます。
楽観的な更新の仕組みと、ID の使用がそれに与える影響について:
XHR 応答を処理する同じクロージャー内で確立されたクライアント側 ID を使用し、応答が成功として戻ってきたときにクライアント側 ID をクリアするか、代わりにエラーでロールバックすることができます。クロージャーにより、応答が返されるまでクライアント側の ID を保持できます。
多くの人が、クライアント側の ID と要求/応答を保持するクロージャーに関連するすべてのメソッドを含む WebAPIUtils モジュールを作成します。アクションの作成者 (またはストア) は、この WebAPIUtils モジュールを呼び出して、要求を開始できます。
したがって、次の 3 つのアクションがあります。
- リクエストを開始する
- 成功を処理する
- 応答を処理する
リクエストを開始するアクションに応答して、ストアはクライアント側の ID を受け取り、レコードを作成します。
成功/エラーに応答して、ストアは再びクライアント側 ID を受け取り、レコードを実際の ID を持つ確認済みレコードに変更するか、代わりにレコードをロールバックします。また、ユーザーに再試行させるなど、そのエラーに関する優れた UX を作成することもできます。
コード例:
// Within MyAppActions
cardAdded: function(columnID, title, text) {
var clientID = this.createUUID();
MyDispatcher.dispatch({
type: MyAppActions.types.CARD_ADDED,
id: clientID,
columnID: columnID,
title: title,
text: text,
});
WebAPIUtils.getRequestFunction(clientID, "http://example.com", {
columnID: columnID,
title: title,
text: text,
})();
},
// Within WebAPIUtils
getRequestFunction: function(clientID, uri, data) {
var xhrOptions = {
uri: uri,
data: data,
success: function(response) {
MyAppActions.requestSucceeded(clientID, response);
},
error: function(error) {
MyAppActions.requestErrored(clientID, error);
},
};
return function() {
post(xhrOptions);
};
},
// Within CardStore
switch (action.type) {
case MyAppActions.types.CARD_ADDED:
this._cards[action.id] = {
id: action.id,
title: action.title,
text: action.text,
columnID: action.columnID,
});
this._emitChange();
break;
case MyAppActions.types.REQUEST_SUCCEEDED:
var tempCard = this._cards[action.clientID];
this._cards[action.id] = {
id: action.id,
columnID: tempCard.columnID,
title: tempCard.title,
text: tempCard.text,
});
delete this._cards[action.clientID];
break;
case MyAppActions.types.REQUEST_ERRORED:
// ...
}
名前の詳細とこの実装の詳細にあまり注意を払わないでください (タイプミスやその他のエラーがある可能性があります)。これは、パターンを説明するためのコード例です。