在阵列控制器中观察对ItemController的更改 [英] Observing changes to an ItemController in Array Controller

查看:82
本文介绍了在阵列控制器中观察对ItemController的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在通过在EmberCli中重新创建TodoMVC来学习余烬。我已经重新创建了所有功能,但遇到一个问题,我希望有人能对此情况有所了解。

I've been learning ember by recreating the TodoMVC in EmberCli. Ive recreated all the functionality, but I ran into an issue and I was hoping someone could shed some light on the situation.

似乎我的Todos ArrayController会观察并触发当模型中的属性发生变化时函数起作用,但是Todo ObjectController中的值发生变化时函数没有变化。

It seems that my Todos ArrayController will observe and fire functions when properties in my model change but not when values in my Todo ObjectController change.

我将isEditing移入了模型,以便在调用 editTodo时 canToggle 触发。但是我更愿意将该值存储在控制器中,而不是模型中。

I moved isEditing into the Model so that when I call editTodo canToggle fires. But I would prefer to store that value in my controller and not the model.

我使用propTest布尔值设置了一个测试。在按钮上单击我触发 propToggle ,但 todoPropToggle 不响应更改。它唯一一次触发的就是初始化。

I set up a test with with a propTest boolean. on a button click I fire propTogglebut todoPropToggle doesn't respond to the change. The only time that it does ever fire is on initialization.

任何洞察力都将非常有用。

Any insight would be super helpful.

TODOS控制器

import Ember from 'ember';
export default Ember.ArrayController.extend({
actions: {
  createTodo: function() {
    var title = this.get('newTitle');
    if (!title.trim()) {
      return;
    }
    var todo = this.store.createRecord('todo', {
      title: title,
      isCompleted: false,
      isEditing:false
    });

    this.set('newTitle', '');
    todo.save();
    }
  },

  canToggle: function() {
    var isEditing = this.isAny('isEditing');
    return this.get('length') && !isEditing;
  }.property('length','@each.isEditing'),

  todoPropToggle: function() {
    var hasPropTest = this.isAny('propTest');
    return hasPropTest;
  }.property('@each.propTest')
});

TODO CONTROLLER

TODO CONTROLLER

import Ember from 'ember';

export default Ember.ObjectController.extend({

  actions: {
    editTodo: function() {
      var todo = this.get('model');
      todo.set('isEditing', true);
    },

    removeTodo: function() {
      var todo = this.get('model');
      todo.deleteRecord();
      todo.save();
    },

    acceptChanges: function() {
      var todo = this.get('model');
      todo.set('isEditing', false);
      if (Ember.isEmpty(this.get('model.title'))) {
        this.send('removeTodo');
      }
      else {
        this.get('model').save();
      }
    },

    propToggle:function(){
      this.set('propTest',!this.get('propTest'));
    }
  },

  propTest:true,

  isCompleted: function(key, value) {
    var model = this.get('model');
    if (value === undefined) {
      return model.get('isCompleted');
    }
    else {
      model.set('isCompleted', value);
      model.save();
      return value;
    }
  }.property('model.isCompleted')
});


推荐答案

propTest 看起来像是一个计算的属性,而不是可观察的。 (编辑:并不是说计算出的属性没有底层的可观察变量为它们提供动力,但是它们的用法有很大不同,以至于我希望将它们分开。)当底层的propTest触发时,它将触发,但是如果没有变化,则ember将在运行循环中不要操作。如果您希望这是一个原始的可观察性,请使用 observes()语法。 @each 可以在这里工作,但是我喜欢保持明确,并且可以观察到它需要更新的内容,而不是使用计算属性,除非我需要直接访问该属性以进行绑定在模板中。

propTest in this scenario here looks like it's a computed property, and not an observable. (edit: not that computed properties don't have underlying observables powering them, but they're different in usage enough that I like to keep them separate) It'll fire when the underlying propTest fires, but if there's no change, ember will no-op that out in the run loop. If you'd rather this be a raw observable, use the observes() syntax. @each will work here, but I like being explicit and have an observable update what it needs to rather than using the computed property, unless I need direct access to that property to bind with in a template.

仅执行时触发源于创建的计算属性的初始绑定。如果之后没有触发,则您用于计算属性 @ each.propTest 的基础绑定必须不正确,否则确实会触发。

The "only firing on execution" stems from the initial bindings from the computed property getting created. If it never fires after that, the underlying bindings you're using for the computed property @each.propTest must be incorrect, otherwise that would indeed fire.

我认为您可能也对ObjectController的目的感到困惑。 Ember.Object 可以完成控制器可以执行的所有可观察的业务,而没有模型或内容属性作为后盾。似乎您可能想要在这里使用一个直立的物体,而不是控制器来做待办事项,因为ember并没有真正的模型类型。然后,我将对象本身作为ArrayController内容的一部分,这时@each可以按照您的期望对其进行迭代。

I think you may also be confused to the purpose of an ObjectController. An Ember.Object can do all of the observable business that a controller can, short of having a 'model' or 'content' property backing it. It looks like you may want to go with a straight up object rather than a controller here for the todo, since ember doesn't really have a 'model' type. I'd then put the objects themselves as part of the content of the ArrayController, at which point @each would be able to iterate on them as you'd expect.

ObjectController的使用级别与ArrayController相同。您当然可以像在这里完成的那样嵌套它们,但是我的间谍意识使人感到刺痛,这对于应用程序是错误的。您可能不需要为每个待办事项对象都配备一个后备控制器,只需要待办事项对象本身即可。

The ObjectController sits at the same level of usage as an ArrayController. You can certainly nest them as you've done here, but my spidey-sense is tingling that it's the wrong thing to do given the application. You probably don't need to have a backing controller for each todo object, you just need the todo object itself.

这篇关于在阵列控制器中观察对ItemController的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆