#4 计算属性

英文原版:https://guides.emberjs.com/v2.13.0/object-model/computed-properties/

计算属性是个什么鬼?

简而言之,计算属性就是可以把属性的值声明为一个函数。当你定义了一个计算属性的时候,并且当你调用这个属性的时候,Ember会自动为你执行属性对应的函数。你可以完全把它当做普通属性,或者是静态属性那么去用。

这可以让你非常方便的一次性操作多个属性,并得到一个新的结果。

开始行动

我们来弄个简单的例子。现在我们有一个Person对象,这个对象有firstName和lastName两个属性,但是我们现在想要有这两个属性组成的全名。并且这个全名显示的结果会随着firstName和lastName的改变而改变:

Person = Ember.Object.extend({
  // these will be supplied by `create`
  firstName: null,
  lastName: null,

  fullName: Ember.computed('firstName', 'lastName', function() {
    let firstName = this.get('firstName');
    let lastName = this.get('lastName');

    return `${firstName} ${lastName}`;
  })
});

let ironMan = Person.create({
  firstName: 'Tony',
  lastName:  'Stark'
});

ironMan.get('fullName'); // "Tony Stark"

属性fullName就是声明的计算属性,firstName和lastName作为它的依赖。当你第一次使用fullName属性的时候,computed()会被调用并且将回调函数中的结果缓存。当你下次直接调用fullName的时候,它的结果会直接从缓存中获取。如果你改变了它的任何一个依赖,即:firstName和lastName的值,那么缓存就会失效,这时候computed()会重新执行,这时你将得到新的结果。

用一个对象声明多个依赖

在上面的例子中,fullName属性依赖了2个属性。

…
  fullName: Ember.computed('firstName', 'lastName', function() {
    let firstName = this.get('firstName');
    let lastName = this.get('lastName');

    return `${firstName} ${lastName}`;
  })
…

我们也可以使用括号表达式来申明依赖,就像下面这样:

…
  fullName: Ember.computed('{firstName,lastName}', function() {
    let firstName = this.get('firstName');
    let lastName = this.get('lastName');

    return `${firstName} ${lastName}`;
  })
…

这么声明,会在你的依赖是json对象的时候尤其有用:

let obj = Ember.Object.extend({
  baz: {foo: 'BLAMMO', bar: 'BLAZORZ'},

  something: Ember.computed('baz.foo', 'baz.bar', function() {
    return this.get('baz.foo') + ' ' + this.get('baz.bar');
  })
});

括号表达式方式:

let obj = Ember.Object.extend({
  baz: {foo: 'BLAMMO', bar: 'BLAZORZ'},

  something: Ember.computed('baz.{foo,bar}', function() {
    return this.get('baz.foo') + ' ' + this.get('baz.bar');
  })
});

计算属性链

你还可以把计算属性当做依赖,这样会形成一个计算属性链。现在再添加一个description计算属性:

Person = Ember.Object.extend({
  firstName: null,
  lastName: null,
  age: null,
  country: null,

  fullName: Ember.computed('firstName', 'lastName', function() {
    return `${this.get('firstName')} ${this.get('lastName')}`;
  }),

  description: Ember.computed('fullName', 'age', 'country', function() {
    return `${this.get('fullName')}; Age: ${this.get('age')}; Country: ${this.get('country')}`;
  })
});

let captainAmerica = Person.create({
  firstName: 'Steve',
  lastName: 'Rogers',
  age: 80,
  country: 'USA'
});

captainAmerica.get('description'); // "Steve Rogers; Age: 80; Country: USA"

动态更新

计算属性,默认的会监听它所依赖的属性的变化,并且会在依赖发生变化时被调用并进行自动更新。下面作一个演示:

captainAmerica.set('firstName', 'William');

captainAmerica.get('description'); // "William Rogers; Age: 80; Country: USA"

可以看到,fullName因为firstName的变化而变化,进而又引起description的变化。

对依赖的属性做任何改变都会引起依赖链上的其他计算属性的变化,直到依赖链的末尾。

设置计算属性

你也可以配置当你操作计算属性的时候需要它干什么。当你要给它一个值的时候(此时会调用setter方法;相反的,会调用getter方法),它会需要你传入一个key和对应的value给它。同时,你需要把你想要缓存在计算属性中的那个值return:

Person = Ember.Object.extend({
  firstName: null,
  lastName: null,

  fullName: Ember.computed('firstName', 'lastName', {
    get(key) {
      return `${this.get('firstName')} ${this.get('lastName')}`;
    },
    set(key, value) {
      let [firstName, lastName] = value.split(/\s+/);
      this.set('firstName', firstName);
      this.set('lastName',  lastName);
      return value;
    }
  })
});


let captainAmerica = Person.create();
captainAmerica.set('fullName', 'William Burnside');
captainAmerica.get('firstName'); // William
captainAmerica.get('lastName'); // Burnside

计算属性宏

大多数你要定义的计算属性的形式都基本一样。不过Ember也提供一些宏,用来再某些特定的场景声明计算属性。

例子,下面这两个计算属性功能上时等价的:

Person = Ember.Object.extend({
  fullName: 'Tony Stark',

  isIronManLongWay: Ember.computed('fullName', function() {
    return this.get('fullName') === 'Tony Stark';
  }),

  isIronManShortWay: Ember.computed.equal('fullName', 'Tony Stark')
});

查阅完整的计算属性宏,移步看一下这里

本节完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值