Ember.get()和this.get()之间的区别

时间:2016-11-15 09:56:42

标签: ember.js

我是Ember的新手,我一直在混淆Ember.get()Font serif = new Font("Serif ", Font.BOLD, 24); for (JLabel l : new JLabel[] { L1, L2, L3, L4, L5, L6, L7, L8 }) l.setFont(serif); 之间的区别。有人可以简要解释一下吗?

3 个答案:

答案 0 :(得分:24)

欢迎来到Ember; - )

扩展Ember Observable mixin的每个对象都支持get()方法(以及其他方法)。

当你调用this.get()时,this必须引用这样一个对象(Route,Controller,Component,你自己的扩展Ember.Object的类等等)。在普通对象上调用get()会导致失败。让我说明一下差异:

const emberObjectInstance = Ember.Object.create({
 name: 'Bala'
});

emberObjectInstance.get('name'); // returns 'Bala'

const plainObject = { name: 'Bala'};
plainObject.get('name'); // causes a failure since get() is not a function

但是,在两种情况下都使用Ember.get()次成功:

Ember.get(emberObjectInstance, 'name'); // returns 'Bala'
Ember.get(plainObject, 'name');         // returns 'Bala', too

也可以用导入编写如下

import { get } from '@ember/object';

get(emberObjectInstance, 'name'); // returns 'Bala'
get(plainObject, 'name');         // returns 'Bala', too

注意:不要忘记,调用get()中的任何一个会使计算属性得到计算(在最常见的情况下,我现在不想深入研究 - 懒惰计算,易变扩展等),但是为了理解差异,我们可以使用普通值。

根据自己的经验,我使用Ember.get()我知道普通对象可能是我需要检索其属性的对象。一个很好的例子是setupController()钩子,我可以从我的单元测试中传递普通对象来测试setupController()的功能。

// some route:
setupController(controller, model){
    this._super(...arguments);

    const name = Ember.get(model, 'name'); // ***

    controller.set('isNamePresentOnSetup', Ember.isPresent(name));
}

// in my unit tests I can use plain object:
...
const modelMock = { name: 'Bala' }; // plain object is enough because I use Ember.get instead of model.get() (see ***)?
const controllerMock = Ember.Object.create(); // has to be Ember.Object since I use controller.set() within setupController()

subject.setupController(controllerMock, modelMock);
assert.ok(controllerMock.get('isNamePresentOnSetup'), "property 'isNamePresentOnSetup' set up correctly if model name is present");
...

我也可以使用Ember.set(controller, 'isNamePresentOnSetup', Ember.isPresent(name)),然后将普通控制器模拟传递给setupController()

我认为这是一个很好的开始,因为你是Ember的新人,我相信Ember大师会有更多的东西要补充。 相关的Ember文档:

https://guides.emberjs.com/v2.9.0/object-model/

https://guides.emberjs.com/v2.9.0/object-model/computed-properties/

https://guides.emberjs.com/v2.9.0/object-model/reopening-classes-and-instances/

<强>更新get()chained paths一起使用与使用POJO不同。 例如,objectInstance.get('a.b.c')如果bundefined,则返回值为undefined objectInstance.a.b.c时将其转换为undefined会引发异常。

答案 1 :(得分:4)

没有。 foo.get('bar')相当于Ember.get(foo, 'bar')。但是,因为在foo.get上定义Ember.Object,您只能在Ember Objects上调用.get()Ember.get()将适用于所有ember对象。在Ember对象上Ember.get(foo, 'bar')相当于foo.get('bar'),在每个其他对象上相当于foo['bar']

答案 2 :(得分:3)

请注意,如果运行2018年4月发布的Ember> = 3.1,则在大多数用例中不再需要使用Ember.get()this.get()。现在可以使用本机ES5 getter。在release notes for Ember 3.1中可以找到有关此更改的快速介绍。 RFC 281中对此进行了更详细的讨论。

有一种代码模式可以帮助您过渡到ES5吸气剂:es5-getter-ember-codemod它可以作为ember-cli-update的一部分运行。

请不要拒绝使用Ember.get()this.get()。对于某些极端情况,仍然需要使用,上面链接的发行说明中列出了这些情况:

  

实际上,在许多情况下您仍必须使用get:

     
      
  • 如果要呼叫,请使用链式路径。例如在this.get('a.b.c')中,如果b未定义,则返回值未定义。当b未定义时将其转换为this.a.b.c会引发异常。
  •   
  • 如果您的对象使用的是unknownProperty,则必须继续使用get。在具有unknownProperty的对象上使用ES5 getter将导致开发中的断言失败。
  •   
  • 当您从其他API读取异步关系时,Ember Data返回Promise代理对象。 Ember代理对象(包括Promise代理)仍要求您调用get来读取值。
  •   

请注意,如果使用ember-changeset,则是一种特殊情况。它提供了自己的.get()实现。因此,如果Ember.get(this, 'value')this.get('value'),则thisember-changeset会有不同的结果。您可以在documentation of ember-changeset中找到有关该案例的更多信息。