2

最终更新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”电子邮件登录。然后,如果您单击第一个答案,您应该会看到一个切换问题表单的“编辑问题”链接。现在,打开该表单,如果您更改问题,该表单仍然可用,新问题作为内容,这是我想要避免的行为。

4

4 回答 4

4

@goffredder 和@Raymond Liu,canEditQuestion函数/属性未触发的原因如下。

在 Ember.js 中,(计算的)属性评估是“神奇的”,但众所周知 - “神奇”可能很昂贵。因此,计算属性的值被缓存,因此“魔术”不必一直发生,除非发生变化,否则不会重新计算缓存值。不仅如此,如果该属性没有显示在屏幕上 - 为什么还要重新计算它?请参阅jsbin 以准确了解我在说什么。请注意,由于属性从未显示在屏幕上,因此永远lazyPropDep不会更新。lazyDep

现在,回到你的例子。canEditQuestion编辑问题时,属性不会呈现到屏幕上(因为它位于 else 块中)。因此,canEditQuestion重置isEditing为 false 的函数永远不会被调用。

我认为您需要将重置逻辑放入观察者中,同时将其他逻辑留在属性中,如下所示:

resetIsEditing : function() {
  this.set('isEditing', false);
}.observes('model.id'),

canEditQuestion : function() {
  return this.get('author.id') === App.currentUser;
}.property('model'),

这样每次新模型(具有新模型 id)被加载到控制器中(即使以前的模型处于编辑模式),观察者代码将触发重置isEditing属性以false

于 2014-12-18T20:30:13.520 回答
2

更新:我误解了你的问题。您想在回答另一个问题时禁用表格,对吗?在您的 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 函数/属性,我认为这正是需要解决的问题。我不知道为什么。

于 2014-12-15T15:52:02.583 回答
1

看起来您的计算属性似乎取决于两个变量,author.id并且App.CurrentUser未在依赖键列表中列出。相反,您仅将其列为model依赖键。我不知道author和之间的关系是什么model,但是您应该列出计算属性所需的实际属性/变量。

于 2014-12-15T15:08:16.837 回答
0

你可以做类似的事情:

<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>
于 2014-12-15T04:48:22.220 回答