私は ember(+data) を使用して簡単なサインアップ フォームを作成しましたが、サーバー側の検証エラーの後、フォーム (および ember-data トランザクション) を適切に機能させるのに問題があります。
トランザクションの使用方法のガイドとしてhttps://github.com/dgeb/ember_data_exampleに従っています。ほとんどの場合、ハッピー パスで機能しますが、サーバー側の検証エラーの後、ember-data を取得できません。 [送信] をクリックしたときに API 要求を再送信します。
私はいくつか掘り下げましたが、モデルが無効になった後のトランザクションのリセットに関連するステップが欠けていると思います...
Github とアプリ
http://emb.herokuapp.com/でアプリを試して問題を再現できます。
https://github.com/justinfaulkner/ember-data-resubmitで完全なソース コードを調べることもできます。
再現
@example.comの電子メール アドレスを使用してアプリのフォームに入力すると、偽のサーバー側エラーをトリガーできます。Rails API は 422 と、ユーザー名/メール フィールドをキーとするエラー オブジェクトを返します。
フィールドはエラーで赤く強調表示されます。電子メール アドレスを有効なものに編集し、もう一度 [送信] をクリックします。クロムで開いている開発者ツールでは、クリックで http リクエストを送信する ember-data が表示されません (ただし、コントローラーの console.log は、クリックが実際に受信されていることを示しています)。
何が起こるべきか
エラーでフィールドを変更した後、ember-data (私が思うに) はモデルを からinvalid
に変更し、次に呼び出されたuncommitted
ときに送信されるようにします。commit
Submit をクリックすると、ember-data は HTTP リクエストを API に送信し、ember は「Congrats!」に遷移するはずです。ページ。
ただし、代わりに、フォームはそこにあるだけです。http リクエストはありません。「おめでとう!」への遷移なし。
入力を更新した後、[送信] を数回 (18 回) クリックした後のスクリーンショットを次に示します。
切れ端
私のemberアプリのスニペットは次のとおりです。
インデックスルート
startEditing
ember_data_example のように使用する私のルートは次のとおりです。
App.IndexRoute = Ember.Route.extend({
model: function() {
return null;
},
setupController: function(controller) {
controller.startEditing();
},
deactivate: function() {
this.controllerFor('index').stopEditing();
}
});
インデックスコントローラー
私IndexController
のはember_data_exampleの後にモデル化されていますContactsNewController
App.IndexController = Ember.ObjectController.extend({
startEditing: function() {
this.transaction = this.get('store').transaction();
this.set('content', this.transaction.createRecord(App.User));
},
submit: function(user){
console.log("submitting!");
this.transaction.commit();
this.transaction = null;
},
_transitionOnSuccess: function(stuff) {
if (this.get('content.id') && this.get('content.id').length > 0) {
console.log("_transitionOnSuccess");
this.transitionToRoute('success');
}
}.observes('content.id'),
stopEditing: function() {
if (this.transaction) {
this.transaction.rollback();
this.transaction = null;
}
}
});
ユーザー
これが私のモデルです。私はember-validationsを使用しています。
App.User = DS.Model.extend(Ember.Validations.Mixin);
App.User.reopen({
username: DS.attr('string'),
password: DS.attr('string'),
profile: DS.belongsTo('App.Profile'),
validations: {
username: {
presence: true
},
password: {
presence: true,
length: { minimum: 6 }
}
}
});
index.hbs
これが私のハンドルバー テンプレートのフォームです。私はember-easyFormを使用しています。
{{#formFor controller}}
<div class="row">
<div class="large-12 columns">
{{input username placeholder="Email address"}}
</div>
</div>
<div class="row">
<div class="large-12 columns">
{{input password placeholder="Password"}}
</div>
</div>
{{submit "Sign Up" class="button"}}
{{/formFor}}
ライブラリの作成者がこの投稿を見る場合に備えて、このコミットでアプリの ember-easyForm と ember-validations のコピーにいくつかのローカル変更を加えました: https://github.com/justinfaulkner/dockyard-example/commit/f618b0e4fb72314d56bb3a9d95e1325925ba6ad0。ただし、変更が問題を引き起こしているとは思いません。
無効になってロールバック?
ここで似たような質問に出くわしました:Ember Data and dirty recordsですが、トランザクションをロールバックするためにaを追加するUser.becameInvalid
と、再送信しようとするとフォームが空になりました(それでも、ember-dataがhttpを再送信しても成功しません)リクエスト)。
ありがとう!
私はember_data_example
うまくフォローしていない(またはユースケースに拡張できていない)か、どこかで単純な間違いを犯していると確信しています...
前もって感謝します。
4月5日編集
これまでのところ、少なくとも 2 つの主な問題を見つけることができます。
this.transaction = null;
これは必要ですか?代わりに何をすべきですか?- 私は削除しようとし
this.transaction = null;
ましたが、ember-data は実際にコミットしようとしました (ただし、まだ ajax リクエストを送信しません)。ここで、無効なフィールドに入力すると、ember-data がレコードをuncommitted
/created
...に更新しようとしていることがわかりますが、別のトランザクションで実行されます。
トランザクションIDが何であるかを出力するember-dataに no-null
いくつかのsがあるレポにブランチをプッシュしました...これが私のコンソールのスナップショットです:console.log
recordBecameDirty
フィールドに入力すると呼び出されます。Ember-data はレコードを更新して、再びコミットできるようにします。しかし、それは他のトランザクションでそれを行っています (458)
しかし、送信ボタンは元のトランザクション (316) に関連付けられており、そのトランザクションでコミットする準備ができているレコードはありません....うーん....