22
Todos.TodoController = Ember.ObjectController.extend({
  isCompleted: function(key, value){
    var model = this.get('model');

    if (value === undefined) {
      // property being used as a getter
      return model.get('isCompleted');
    } else {
      // property being used as a setter
      model.set('isCompleted', value);
      model.save();
      return value;
    }
  }.property('model.isCompleted')
});

我正在阅读 Ember.js 的 ToDo 指南,但我似乎无法理解这个控制器是如何工作的。.property() 是什么意思?以及当我删除“返回值”时怎么办?行功能保持不变。如果有人可以准确地解释这里发生了什么,那就太好了。

指南链接:http ://emberjs.com/guides/getting-started/marking-a-model-as-complete-incomplete/

4

2 回答 2

21

在 javascript 中,获取或设置一个属性时进行某些处理的唯一方法是使用Object.defineProperty

Object.defineProperty(person, "b", {
  get : function() { 
    return person.firstName + ' ' + person.surname; 
  },
  set : function(newValue) {
    var names = newValue.split(' '); 
    person.firsname = names[0];
    person.surname = names[1]; 
  },
  enumerable : true,
  configurable : true
});

但这有一些缺点:

  • 不是跨浏览器
  • 没有绑定,换句话说,如果firstnamesurname更改,则依赖属性fullname不会更改。
  • 调用person.namewhenperson未定义,会抛出错误
  • 不可能触发观察者,没有额外的代码并且知道依赖层次:firstnamedepends from fullname,它可以是其他属性的依赖啊!

因此,Ember 具有“属性”的概念,称为计算属性

可以通过两种方式声明:

foo: Ember.computed(function({
  ...
}).property(dependent keys);

或使用(默认)时Ember.ENV.EXTEND_PROTOTYPES = true

foo: function() {
  ...
}.property(dependent keys);

, 是必需的property(dependent keys),因为它告诉 ember 什么是在更改时将更新属性的属性。

fullname: function(key, value) {
  // setter
  if (value !== undefined) {
    var names = value.split(' ');
    this.set('firstname', names[0]);
    this.set('surname', names[1]);
  }
  // always return the complete result, so nexts calls to this.get('fullname') will return the cached value  
  return this.get('firstname') + ' ' + this.get('surname');
}.property('firstname', 'surname')

使用它,您具有以下优势:

  • 当更改firstname或更改surname为新值时,fullname会更改。
  • beforeObserves改变值之前触发,改变值之后observes触发。
  • 任何引用某些属性的模板都会更新
  • 对 person.get('firstname') 的多次调用将返回一个缓存值,从而节省处理。您可以使用禁用此功能.property(..).volatile()
  • 在访问 null 对象时避免 null 或 undefined 错误,例如:如果 person 或 dog 未定义,则controller.get('person.dog.name')返回。undefined

我希望它有帮助

于 2013-09-04T14:08:07.950 回答
7

.property()将函数标记为计算属性,以便它可以在模板中使用,例如,以一致的方式。它是 JavaScript 属性foo吗?或者它是一个功能foo()?计算属性在所有平台上解决了这个问题。

作为参数传递的字段和路径是依赖键。Ember 中的所有计算属性都默认缓存。要知道何时需要重新计算计算属性,Ember 需要知道它依赖于哪些属性和路径。在指南的示例中,fullName计算属性取决于firstNameand lastName; Ember 需要知道这一点,以便fullName在其中任何一个发生变化时重新计算。(注意:您可以使用 关闭缓存.property().volatile()。)

请阅读指南。所有这些都记录在那里。

于 2013-09-04T13:36:30.407 回答