[英]Ember.js not updating model
最终更新 : Kalman Hazins指出我正确的方向,计算属性没有被调用,因为它没有在屏幕上呈现,所以重新计算它并不是“必要的”。 我将在这里包含控制器的最终代码:
App.QuestionController = Ember.ObjectController.extend({
isEditing : false,
resetIsEditing : function() {
this.set('isEditing', false);
}.observes('model.id'),
canEditQuestion : function() {
return this.get('author.id') === App.currentUser;
}.property('author.id')
}
更新:下面的Raymond Liu提供了一个“足够好”的解决方案,它并没有真正回答“为什么会这样”的问题,但这是迄今为止我所能做到的最好的。
我正在学习Ember.js,关注这本书并做出一些改变。 在我的控制器中,我具有绑定到模型的属性,但是当我更改此类模型时,该属性不会更新。
这是控制器:
App.QuestionController = Ember.ObjectController.extend({
isEditing : false,
canEditQuestion : function() {
this.set('isEditing', false);
return this.get('author.id') === App.currentUser;
}.property('model')
});
这是模板:
<script type="text/x-handlebars" id="question">
{{#if isEditing}}
<!-- edit question form -->
{{else}}
<p id="question">{{question}}</p>
{{#if canEditQuestion}}
<a href="#" {{action "toggleEditQuestion"}}>Edit question</a>
{{/if}}
{{/if}}
</script>
请注意,如果我将{{else}}
分支内容{{#if isEditing}}
它将按预期工作(但不是我想要的那样)。
也许question
是嵌套路线的事实很重要:
App.Router.map(function() {
this.resource('questions', function() {
this.resource('question', { path : '/:question_id' });
});
});
我想要的是,即使我已经在编辑问题,如果更改模型, isEditing
属性也应返回false
并且不显示问题表单。 如果我总是提出问题,显然我可以解决它,但这不是我想要的。 我错过了什么?
编辑:我正在添加question
和user
模型的代码:
App.Question = DS.Model.extend({
title : DS.attr('string'),
question : DS.attr('string'),
date : DS.attr('date'),
author : DS.belongsTo('user', { async : true }),
answers : DS.hasMany('answer', { async : true })
});
App.User = DS.Model.extend({
fullname : DS.attr('string'),
email : DS.attr('string'),
questions : DS.hasMany('question', { async : true })
});
App.currentUser
属性在sign_in
控制器中设置:
App.SignInController = Ember.Controller.extend({
needs : [ 'application' ],
actions : {
signIn : function() {
var email = this.get("email");
var userToLogin = App.User.FIXTURES.findBy("email", email);
if(userToLogin === void 0) {
alert("Wrong email!");
this.set("email", "");
}
else {
localStorage.currentUser = userToLogin.id;
App.set('currentUser', userToLogin.id);
}
}
}
});
PS:我的应用程序的完整代码可以在https://github.com/goffreder/emberoverflow上找到
PS2:我设法获得了可运行的jsFiddle应用程序。 要复制,您必须使用“ tom@dale.com”电子邮件登录。 然后,如果您单击第一个答案,您应该会看到一个“编辑问题”链接,可切换问题表格。 现在,打开该表单,如果您更改了问题,表单仍然可用,新问题作为内容,这是我想要避免的行为。
@goffredder和@Raymond Liu, canEditQuestion
函数/属性未触发的原因如下。
在Ember.js中,(计算)属性评估是“神奇的”,但众所周知 - “魔术”可能很昂贵。 因此,将缓存已计算属性的值,这样就不必一直都在发生“魔术”,除非对缓存值进行某些更改不会重新计算。 不仅如此,如果该属性未显示在屏幕上-为什么还要重新计算它? 看到这个 jsbin,看看我在说什么。 请注意lazyPropDep
永远不会更新,因为lazyDep
属性永远不会显示在屏幕上。
现在,回到你的例子。 编辑问题时, canEditQuestion
属性不会呈现在屏幕上(因为它位于else块中)。 因此, canEditQuestion
其复位功能isEditing
从来没有假被调用。
我认为你需要的是将重置逻辑放入观察者,同时将其他逻辑留在属性中,如下所示:
resetIsEditing : function() {
this.set('isEditing', false);
}.observes('model.id'),
canEditQuestion : function() {
return this.get('author.id') === App.currentUser;
}.property('model'),
这样,每次将新模型(具有新模型ID)加载到控制器中(即使先前模型处于编辑模式),观察者代码也会触发将isEditing
属性重置为false
更新 :我误解了你的问题。 你想在转到另一个问题时禁用表格,对吧? 在您的question_routs.js文件中,添加以下内容:
App.QuestionRoute = Ember.Route.extend({
actions: {
didTransition: function() {
this.controller.set('isEditing', false);
return true; // Bubble the didTransition event
}
}
})
当您转换到另一个问题时,这些代码会将'isEditing'属性设置为false。 我注意到,当isEiting属性设置为true时,切换到另一个问题时不会调用canEditQuestion函数/属性,我认为这是需要解决的问题。 我不明白为什么。
看来您的计算属性取决于两个变量, author.id
和App.CurrentUser
未在从属键列表中列出。 相反,您只将model
列为依赖键。 我不知道author
和model
之间的关系是什么,但是您应该列出计算属性所需的实际属性/变量。
您可以执行类似的操作:
<script type="text/x-handlebars" id="question">
{{#unless isEditing}}
<p id="question">{{question}}</p>
{{#if canEditQuestion}}
<a href="#" {{action "toggleEditQuestion"}}>Edit question</a>
{{/if}}
{{else}}
<!-- edit question form -->
{{/unless}}
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.