.property()做什么?in function(){}.property()

Wil*_*red 20 javascript ember.js

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')
});
Run Code Online (Sandbox Code Playgroud)

我正在通过Ember.js的ToDo指南,我似乎无法理解这个控制器是如何工作的..property()是什么意思?当我删除'返回值'时怎么样?行功能保持不变.如果有人能够准确地解释这里发生的事情会很棒.

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

Mar*_*ior 20

在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
});
Run Code Online (Sandbox Code Playgroud)

但这有一些缺点:

  • 不是跨浏览器
  • 没有绑定,换句话说,如果firstnamesurname更改,依赖属性fullname不会更改.
  • 调用person.namewhen person未定义时,会抛出错误
  • 是不可能触发观察者,没有额外的代码并且意识到依赖性层次结构:firstname取决于fullname,它可以是其他属性的依赖性arghhh!

由于这个Ember具有"属性"的概念,称为计算属性.

它可以通过两种方式声明:

foo: Ember.computed(function({
  ...
}).property(dependent keys);
Run Code Online (Sandbox Code Playgroud)

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

foo: function() {
  ...
}.property(dependent keys);
Run Code Online (Sandbox Code Playgroud)

property(dependent keys)是必需的,因为它告诉我们什么是更改后的属性,将使属性更新.

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')
Run Code Online (Sandbox Code Playgroud)

使用此功能,您可以获得以下优势:

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

我希望它有所帮助


Jon*_*ran 6

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

作为参数传递的字段和路径是从属键.默认情况下,Ember中的所有计算属性都将被缓存.要知道何时需要重新计算计算属性,Ember需要知道它所依赖的属性和路径.在指南的示例中,fullName计算属性取决于firstNamelastName; Ember需要知道,所以fullName当其中任何一个改变时它都可以重新计算.(注意:您可以使用.property().volatile().来关闭缓存.)

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

  • @DanielLizik,“.property()”语法已经有一段时间没有出现在指南中了。请参阅[指南的版本 1.12.0](https://guides.emberjs.com/v1.12.0/object-model/compulated-properties/) 了解最后一次包含的内容。当前推荐的方法是使用 `Ember.compulated('firstName', 'lastName', function() { ... })`。功能是一样的。 (2认同)