Ember 翻译——对象模型:二、类和实例

20 篇文章 0 订阅

类和实例

当你学习 Ember 的时候,你会看见像 Ember.Component.extend()DS.Model.extend() 这样的代码。在这里,你将学习这个 extend() 方法以及 Ember 对象模型的其它的一些主要特性。

定义类

要定义一个新的 Ember 类,请调用 Ember.Object 上的 extend() 方法:

const Person = Ember.Object.extend({
    say(thing) {
        alert(thing);
    }
});

这将定义一个拥有 say() 方法的 Person 类。

你也可以通过调用任何一个存在的类 extend() 方法,来创建的子类。例如,你可能想要创建 Ember 内置的 Ember.Component 类的一个子类:

app/components/todo-item.js

export default Ember.Component.extend({
    classNameBindings: ['isUrgent'],
    isUrgent: true
});

重写父类方法

当定义一个子类是,你可以重写类方法,但同时也可以通过调用特殊的 _super() 方法来执行父类方法:

const Person = Ember.Object.extend({
    say(thing) {
        alert(`${this.get('name')} says: ${thing}`);
    }
});

const Soldier = Person.extend({
    say(thing) {
        // this will call the method in the parent class (Person#say), appending
        // the string ', sir!' to the variable `thing` passed in
        this._super(`${thing}, sir!`);
    }
});

let heduda = Soldier.create({
    name: 'Yehuda Katz'
});

yehuda.say('Yes');  // alerts "Yehuda Katz says: Yes, sir!"

在某些情况下,你将想要在重写之前或者之后传递参数给 _super()
这将让原本的方法继续如常执行。
在一个 Ember-data 的序列化器中重写 normalizeResponse() 钩子是一个很常见的应用场景。
我们可以使用如 ...arguments 之类的 “扩展运算符”来更快捷地实现:

normalizeResponse(store, primaryModelClass, payload, id, requestType)  {
    // Customize my JSON payload for Ember-Data
    return this._super(...arguments);
}

上面的例子将原始的参数(在你自定义之后)返回给父类,使得它能继续正常执行。

创建实例

一旦你定义了一个类,你可以通过调用其 create() 方法,来创建新的实例。任何你定义在类上的方法、属性和计算属性,都能被实例获得。

const Person = Ember.Object.extend({
    say(thing) {
        alert(`${this.get('name')} says: ${thing}`);
    }
});

let person = Person.create();

person.say('Hello'); // alerts " says:Hello"

当创建一个实例的时候,你可以传递一个可选对象到 create() 方法中,用来初始化实例的属性值。

const Person = Ember.Object.extend({
    helloWord() {
        alert(`Hi, my name is ${this.get('name')`);
    }
});

let tom = Person.create({
    name: 'Tom Dale'
});

tom.helloWord(); // alerts "Hi, my name is Tom Dale"

注意因为性能原因,当调用 create() 方法的时候,你不可以重新定义一个实例的计算属性,也不应该重新定义一个已经存在的方法或者定义一个新的方法。当调用 create() 方法的时候,你应该只设置简单属性。如果你需要定义或重新定义方法,又或者计算属性,请创建一个新的子类,然后实例化它。

按照惯例,保存属性或者变量使用大驼峰命名法,而实例则不然。所以,比如变量 Person 将指向一个类,而 person 将指向一个实例(通常是 Person 的实例)。你需要在你的 Ember 应用中保持这种命名习惯。

初始化实例

当一个新的实例被创建的时候,它的 init() 方法将被自动执行。这是初始化一个实例时完成初始设置的理想位置:

const Person = Ember.Object.extend({
    init() {
        alert(`${this.get('name')}, reporting for duty!`);
    }
});

Person.create({
    name: 'Stefan Penner'
});

// alerts "Stefan Penner, reporting for study!"

如果你选择继承一个框架内置类,比如 Ember.Component,并且你重写了 init() 方法,请确保你调用了 this.super(...arguments)!如果你没有,一个父类可能没有机会来执行重要的安装工作,而你将在你的应用中看到奇怪的行为。

在任何 Ember.Object 上直接定义的数组和对象将跨实例共享该对象。

const Person = Ember.Object.extend({
    shoppingList: ['eggs', 'cheese']
});

Person.create({
    name: 'Stefan Penner',
    addItem() {
        this.get('shoppingList').pushObject('bacon');
    }
});

Person.create({
    name: 'Robert Jackson',
    addItem() {
        this.get('shoppingList').pushObject('sausage');
    }
});

// Stefan and Robert both trigger their addItem.
// They both end up with: ['eggs', 'cheese', 'bacon', 'sausage']

为了避免这个行为,我们推荐在 init() 期间初始化这些数组和对象属性。这样做将能保证每一个实例都是特异的。

const Person = Ember.Object.extend({
    init() {
        this.get('shoppingList', ['eggs', 'cheese']);
    }
});

Person.create({
    name: 'Stefan Penner',
    addItem() {
        this.get('shoppingList').pushObject('bacon');
    }
});

Person.create({
    name: 'Robert Jackson',
    addItem() {
        this.get('shoppingList').pushObject('sausage');
    }
});

// Stefan ['eggs', 'cheese', 'bacon']
// Robert ['eggs', 'cheese', 'sausage']

链接对象属性

当连接一个对象的属性的时候,使用 get()set() 连接器方法:

const Person = Ember.Object.extend({
    name: 'Robert Jackson'
});

let person = Person.create();

person.get('name'); // 'Robert Jackson'
person.set('name', 'Tobias Fünke');
person.get('name'); // 'Tobias Fünke'

请确保你使用这些连接器方法;否则,计算属性不会重新计算,观察者不会触发,模板也不会自动更新。


原文地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值