vuvivian's blog

越努力,越幸运.

  1. 1. 创建一个子类
  2. 2. 继承
  3. 3. 混合
  4. 4. 修改现有的类

类系统

Odoo是在ECMAScript 6类可用之前开发的。在ECMAScript 5中,定义类的标准方法是定义一个函数并在其原型对象上添加方法。这很好,但是当我们想要使用继承、混合时,它稍微复杂一些。
出于这些原因,Odoo决定使用自己的类系统,这是受到约翰·雷西格的启发。基类位于web.class文件class.js中。

创建一个子类

让我们讨论如何创建类。主要机制是使用extend方法(这或多或少相当于ES6类中的extend)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Class = require('web.Class');

var Animal = Class.extend({
init: function () {
this.x = 0;
this.hunger = 0;
},
move: function () {
this.x = this.x + 1;
this.hunger = this.hunger + 1;
},
eat: function () {
this.hunger = 0;
},
});

在本例中,init函数是构造函数。它将在创建实例时调用。通过使用new关键字创建实例。

继承

可以方便地继承现有的类。这只需在超类上使用extend方法即可完成。当调用一个方法时,框架会秘密地将一个特殊的方法_super重新绑定到当前调用的方法中。这允许我们在需要调用父方法时使用this._super。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var Animal = require('web.Animal');

var Dog = Animal.extend({
move: function () {
this.bark();
this._super.apply(this, arguments);
},
bark: function () {
console.log('woof');
},
});

var dog = new Dog();
dog.move()

混合

Odoo类系统不支持多重继承,但是对于那些需要共享某些行为的情况,我们有一个混合系统:extend方法实际上可以接受任意数量的参数,并将它们组合到新的类中。

1
2
3
4
5
6
7
8
9
10
11
12
var Animal = require('web.Animal');
var DanceMixin = {
dance: function () {
console.log('dancing...');
},
};

var Hamster = Animal.extend(DanceMixin, {
sleep: function () {
console.log('sleeping');
},
});

在这个例子中,Hamter 类是Animal的子类,但是它也混合了DanceMixin.

修改现有的类

这并不常见,但有时我们需要在适当的位置修改另一个类。目标是有一个机制来改变一个类和所有未来/现在的实例。这是通过使用include方法完成的:

1
2
3
4
5
6
7
8
var Hamster = require('web.Hamster');

Hamster.include({
sleep: function () {
this._super.apply(this, arguments);
console.log('zzzz');
},
});

这显然是一个危险的操作,应该小心操作。但是,按照odoo的结构,有时需要在一个插件中修改在另一个插件中定义的widget/class的行为。请注意,它将修改类的所有实例,即使它们已经创建。

本文最后更新于 天前,文中所描述的信息可能已发生改变