鉴于以下代码片段,每当我在开发模式下按Edit.hbs上的更新按钮时,Ember.js都会一直按下以下警告:
警告('未能更新用户!')
然而,这个问题的不同之处在于记录在服务器端持有200 (M'kay)
回复,当我在我的实时网站处于生产模式时,Ember.js确认用户已经更新了其他警报()...有关这个问题的根源的任何想法?
我见过很多例子,但我怀疑其中大部分都不再适用于2.0版本的...
路由器
this.route('user', { path:'user/:user_id' }, function() {
this.route('edit');
});
编辑控制器
// Removed extra code that controls warning messages to model.user
// and comparison to model.users
update: function(user) {
// Extra Code that checks current_password and others omitted.
user.save().then(function() {
alert('User Updated!');
// transitionToRoute errors with undefined...
this.controller.transitionToRoute('user', user);
}, function() {
alert('failed to update user!');
});
}
修改路线
export default Ember.Route.extend ({
model: function() {
return Ember.Object.create ({
user: this.modelFor('user'),
users: this.store.findAll('user')
});
}
});
修改模板(仅限按钮)
<button class="button_type1" {{action "update" model.user}}>Update User</button>
Live Website
这将直接带您进入用户#2编辑页面。目前,您可以无限制地访问网站,因为这样可以更容易地捕获错误...更改密码不起作用,但其他属性应该如前所述保持不变。
Source Code
this.transitionToRoute('user', user);
现在按预期工作。
user.save().then(() => {
alert('User Updated!');
this.transitionToRoute('user', user);
}).catch(() => {
alert('User Not Updated!');
});
通过在catch语句中附加理由,我能够缩小我遇到的第二个问题:
user.save().then(() => {
// Not reaching
}).catch((reason) => {
console.log(reason); //Assertion Failed: normalizeResponse must return a valid JSON API document: * Top level of a JSON API document must be an object.
});
服务器终端一直告诉我200 OK,但实际响应在Rails端格式错误。如果遇到类似问题,请在Rails控制器上进行以下更改:
// Outputs Bad JSON
render json: user.update(user_params)
// Output proper JSON
user.update(user_params)
render json: user
答案 0 :(得分:2)
问题在于控制器代码。当你执行user.save()时,它会返回一个promise,对于你调用它的任何函数,上下文将是promise本身所以在你的块'this'指向promise对象而不是路由器实例,所以它不能解析this.controller,因此虽然它保存了你的模型,但控件会进入catch / fail块。要解决这个问题,你可以这样做:
1)将上下文绑定到'then'函数
update: function(user) {
// Extra Code that checks current_password and others omitted.
user.save().then(function() {
alert('User Updated!');
// transitionToRoute errors with undefined...
this.controller.transitionToRoute('user', user);
//OR this.transitionTo('user', user);
}.bind(this), function() {
alert('failed to update user!');
});
}
2)将路由器实例存储在'then'之外的变量中,以便在then块中访问
update: function(user) {
// Extra Code that checks current_password and others omitted.
var context = this;
user.save().then(function() {
alert('User Updated!');
// transitionToRoute errors with undefined...
context.controller.transitionToRoute('user', user);
}, function() {
alert('failed to update user!');
});
}
3)或使用ES6箭头功能,它将自动绑定此上下文。我以前没试过这些,但它应该有用。
user.save().then(()=> {
alert('User Updated!');
this.controller.transitionToRoute('user', user);
}, () => {
alert('failed to update user!');
});
希望这有帮助。