#4 计算属性

xiaoxiao2021-02-28  120

英文原版: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') });

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

本节完

转载请注明原文地址: https://www.6miu.com/read-64701.html

最新回复(0)