私は自分のプロジェクトにember-dataを使用していますが、オブジェクトをダーティし、変更をコミットせずに意図的にその状態を再びクリーンに設定する可能性を中心に質問があります。シナリオは次のとおりです。
banana = App.Fruit.find('banana');
を介してオブジェクトをフェッチし、「黄色い果物!」という説明があるとします。 XHRロングポーリング(またはWebSocket)を使用すると、別のユーザーが説明を「おいしい黄色い果物!」に変更したために、オブジェクトの更新バージョンを受け取る場合があります。任意の時点afterで元のオブジェクトをフェッチしました。
次に、新しく受信したデータを反映するようにオブジェクトを更新します。このために、私はさまざまなアプローチを試しました。
App.Store.load(App.Fruit, new_data);
を呼び出してみました。まず第一に、このアプローチは機能しません、そして第二に、これは本当に私が望むものではありません。自分でオブジェクトにコミットされていない変更を加えることもできますが、この場合、それらを単に破棄することは望ましくありません(load()
呼び出しがそれらを上書きすると仮定します)。
オブジェクトのプロパティを新しいデータで更新するために、.set()
-のように:banana.set('description', new_data.description);
-を呼び出して、新しいデータをループしようとしました(該当する場合=ダーティではありません)。これは機能しますが、オブジェクトは汚れた状態のままになります。
オブジェクトを再度クリーン/更新するために-およびnotアダプタに変更をコミットさせます! -オブジェクトが通過する状態を確認しました。これらは(少なくとも):
rootState.loaded.saved
_状態です。.set()
を呼び出すと、プロパティが_rootState.loaded.updated.uncommitted
_状態になります。App.store.commit();
を呼び出すと、オブジェクトは_rootState.loaded.saved
_状態に戻ります。したがって、次のように、手順2の後でオブジェクトの状態を手動でsaved
に設定しようとしました:banana.get('stateManager').goToState('saved');
。
ただし、これは機能しません。次回ストアが他の理由でコミットすると、この操作によりinFlightDirtyReasons is undefinedエラーが生成されます。
私の質問は、汚れたオブジェクトの状態を手動で元に戻してクリーン(保存)に戻すにはどうすればよいですか?
Ember-dataを見ると、コミットされていない状態には「becameClean」イベントがあり、その結果、レコードがloaded.savedとして設定されます。
これはトリックを行う必要があります
record.get('stateManager').send('becameClean');
Ember Data 1.0.0-beta.7の解決策:
// changing to loaded.updated.inFlight, which has "didCommit"
record.send('willCommit');
// clear array of changed (dirty) model attributes
record.set('_attributes', {});
// changing to loaded.saved (hooks didCommit event in "inFlight" state)
record.send('didCommit');
Ember-dataのソースコードを検索したところ、loaded.saved状態には、「保存済み」状態を設定する前に、モデルがクリーンかどうかをチェックするセットアップ機能があることがわかりました。クリーンでない場合は、状態を変更する要求を拒否し、loaded.updated.uncommittedに戻ります。
したがって、クリーンにする必要がありますmodel._attributes配列は、属性名を保持し、Emberを使用すると、状態を手動で変更できます。
モデルのプライベートプロパティを設定する必要があるため、あまり良い解決策ではないことはわかっていますが、他の解決策はまだ見つかりません。
Ember Data 2.6.1のソリューション
record.send('pushedData');
ダーティレコードをロードおよび保存済みとして設定
これは@ Kamil-jのソリューションのアップデートです。
現在使用しているEmber Data 2.0の場合、次の手順を実行する必要があります。
record._internalModel.send('willCommit');
record._internalModel._attributes = {};
record._internalModel.send('didCommit');
_ember-data
_ _1.0.0-beta.12:
_現在
_record.transitionTo('loaded.saved');
_
record.get('stateManager')
はもう必要ないようです。
1.0.0.rc6.2以降...
これにより、モデルが保存されたモデルの状態に移行します。
record.get('stateManager').transitionTo('loaded.saved')
これにより、モデルがコミットされていない新しいモデルの状態に移行します。新しい汚れたモデルを考えてください。
record.get('stateManager').transitionTo('loaded.created.uncommitted')
これにより、モデルが更新された古いモデルの状態に移動します。古いダーティモデルを考えてみてください。
record.get('stateManager').transitionTo('loaded.updated')
エンバー2.9.1
record.set('currentState.isDirty', false);
Ember Data 1.0.0-beta.10:で機能すると思われるものは次のとおりです。
record.set('currentState.stateName', 'root.loaded.saved');
record.adapterWillCommit();
record.adapterDidCommit();
record.set('currentState.isDirty', false);
これらすべての行が必要かどうかはわかりませんが、これより前に他の人が行ったことに従うだけです。
テスト済みEmberデータ2.9
pushDataアクションは進むべき道ですが、それに加えて「originalValues」もリセットする必要があります。
Ember.assign(record.data, record._internalModel._attributes);
Ember.assign(record._internalModel._data, record._internalModel._attributes);
record.send('pushedData');
Ember Data 1.0.0-beta.18:を使用するときに私のために働いた別の方法
record.rollback()
これにより、ダーティ属性が逆になり、レコードがクリーンな状態に戻りました。
record.rollbackAttributes
を支持して、このように廃止された可能性があります: http://emberjs.com/api/data/classes/DS.Model.html#method_rollbackAttributes
私はエンバーデータ1.1に取り組んでいるので、次のソリューションを使用しました(@Martin Malindaによって提供されたものと@Sergeによって提供されたものの混合のようです):
_// Ensure you have the changes inside the record
Object.assign(record.data, record._internalModel._attributes);
Object.assign(record._internalModel._data,record._internalModel._attributes);
// Using the DS.State you can first simulate the record is going to be saved
record.get('_internalModel').send('willCommit');
// Cleaning the prevous dirty attributes
record.get('_internalModel')._attributes = {};
// Mark the record as saved (root.loaded.created.uncommitted) even if it isn't for real
record.get('_internalModel').send('didCommit');
_
このように、このレコードでさらにrollbackAttributes()
を呼び出すと、ダーティな属性がある場合、レコードは(元のプロパティではなく)この最後の状態にリセットされます。私は自分のユースケースで探していました。
ダーティ属性がない場合、何も変更されず、このコードを使用して設定された最後の属性を、元の属性にロールバックせずに保持します。それが役に立てば幸い。
新しいバージョンでは、ここで説明したすべてが壊れたようです。
これはember-data 1.0.0.beta4:でうまくいきました
record.adapterWillCommit();
record.adapterDidCommit();
テスト済みEmberデータ3.8.0
マーティンマリンダの 回答 の更新:
// Clear changed attributes list
record._internalModel._recordData._attributes = {};
// Trigger transition to 'loaded.saved' state
record.send('pushedData');
私の場合、シリアライザーのnormalize
メソッドもオーバーライドする必要がありました。