【发布时间】:2014-12-14 11:07:22
【问题描述】:
最终更新: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,遵循 this 的书并进行一些更改。在我的控制器中,我有一个绑定到模型的属性,但是当我更改此类模型时,该属性不会更新。
这是控制器:
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”电子邮件登录。然后,如果您单击第一个答案,您应该会看到一个切换问题表单的“编辑问题”链接。现在,打开该表单,如果您更改问题,该表单仍然可用,新问题作为内容,这是我想要避免的行为。
【问题讨论】:
-
你不想
author.get('id')吗?除了答案中提出的有关正确编写依赖项的其他要点之外。请记住,.property('model')并不意味着模型中的某些内容发生了变化,而是意味着模型本身——模型对象——变成了不同的模型对象。 -
编辑:对不起,目标错误^_^我为什么要
author.get('id')?这是访问属性的更好方法吗?我知道计算属性依赖于整个模型的不同,而不是它的单个属性,似乎如果我不直接用它的模板渲染它,模型就不会改变。也许应该是这样吧,我不知道(这就是我问的原因^_^) -
在这点上完全同意@torazaburo,一定要正确指定你的依赖。此外,您的模板逻辑没有意义。如果
canEditQuestion为真,您想检查isEditing,而不是相反。此外,您不想触发计算属性中的属性更改。观察者这样做,并且属性应该只用于计算有问题的属性。最后,计算属性只有在被访问时才会被计算,因此将其嵌套在以 false 开头的条件模板中意味着它永远不会被属性更新。 -
@AdamRobertson:“正确指定依赖项”是什么意思?另外,我明白你关于模板的观点,但如果我正在编辑,我不希望呈现
{{question}}模板,所以我必须先检查isEditing。还是我错过了什么? -
正如@torazaburo 提到的,依赖是
author.id,而不是model。您也无法指定App.currentUser的依赖项,因为您在计算属性中使用了对它的全局引用,而且我很确定观察者不适用于全局变量。至于#if 块,您的最终编辑应该注意这一点。我再怎么强调也不过分,以避免在计算属性定义中修改控制器/模型——它更干净,更容易测试。
标签: javascript ember.js ember-model