ODOO前端教程

原创
2019/09/19 17:34
阅读数 3.8K

如何创建一个简单的自定义Widget?

 

在使用了简单的Widget并认识了ODOO中常用的Widget后,想更进一步,创建自己的Widget。

 

首先,需要了解以下:

  • Javascript 基础与实践 
  • jQuery
  • Underscore.js

一个简单的模块:

 

让我们从一个简单的odoo模块开始,该模块包含基本的Web组件配置,并让我们测试Web框架。

 

您可以从网上下载此模块:

$ git clone http://github.com/openerphk/demostore

 

demostore

|-- images

|   |-- alligator.jpg

|   |-- ball.jpg

|   |-- crazy_circle.jpg

|   |-- fish.jpg

|   `-- mice.jpg

|-- __init__.py

|-- demostore.message_of_the_day.csv

|-- __manifest__.py

|-- store_data.xml

|-- store.py

|-- store.xml

`-- static

    `-- src

        |-- css

        |   `-- store.css

        |-- js

        |   `-- store.js

        `-- xml

            `-- store.xml

 

该模块已包含多种服务器端的开发,我们暂时把这些留到后面来讨论。现在让我们集中阐述与Web相关的内容,在static 文件夹里。

demostore/static/css/store.css   当前为空,之后会放入 store 模块的 CSS 内容

demostore/static/xml/store.xml   大部分为空, 之后会放入 qweb  模板

demostore/static/js/store.js     通过JavaScript包含了应用端的大部分逻辑.

如下:

odoo.demostore = function(instance, local) {

    var _t = instance.web._t,

        _lt = instance.web._lt;

    var QWeb = instance.web.qweb;

 

    local.HomePage = instance.Widget.extend({

        start: function() {

            console.log("Store home page loaded");

        },

    });

 

    instance.web.client_actions.add(

        'demostore.homepage', 'instance.demostore.HomePage');

}

 

这段代码,将在浏览器的前端,打印一个 Console log;

 

ODOO中所有静态文件夹中的文件都需要在模块中定义,以便正确加载。src/xml中的所有内容都定义在__manifest__.py中,而src/csssrc/js的内容则在store.xml或类似文件中定义。

注意:

所有的javascript文件都连接在一起, :term:`minified`  以提高应用程序加载时间。这样,排错难度增加了。但通过ODOO的 Debug 模式,可以解决。

                             

 

ODOO JavaScript 模块

JavaScript没有内置模块。导致不同文件中定义的变量混合在一起,会发生冲突。特别是名称空间和限制命名。

所以,odoo框架使用以下模式来定义Web加载项中的模块: 以便有正确的命名空间代码和加载顺序。demostore/static/js/store.js 定义如下:

odoo.demostore = function(instance, local) {

    local.xxx = ...;

}

 

在Odoo Web中,模块被声明为在全局odoo变量上设置的函数。

 

 函数名必须与加载项(在本例中是DemoStore)相同,以便框架能够找到它,并自动初始化它。

 

 

当Web客户端加载模块时,它将调用根函数并提供两个参数:

 

 

  • 第一个参数: 是Odoo Web Client的当前实例,它提供对ODOO(翻译、网络服务)定义的各种功能以及由core或其他模块定义的对象。

 

  • 第二个参数: 是Odoo Web Client自动创建的本地命名空间。它允许模块从外部访问对象和变量。

 

 

 

与模型一样,JavaScript 原生没有 class(类),所以ODOO提供了一个基于 《John Resig's 简单JavaScript继承原理》的类系统。

// 在文件 a.js

odoo.define('module.A', function (require) {

    "use strict";

    var A = ...;

    return A;});

 

// 在文件 b.js

odoo.define('module.B', function (require) {

    "use strict";

    var A = require('module.A');

    var B = ...; // something that involves A

    return B;});

 

新的类都通过调用:func:`~odoo.web.Class.extend` 方法来定义:

 

var MyClass = instance.web.Class.extend({

    say_hello: function() {

        console.log("hello");

    },

});

 

:func:`~odoo.web.Class.extend` 方法通过字典定义输入,例如:say_hello

var my_object = new MyClass();

my_object.say_hello();// console中打印 "hello"

 

属性可以通过 this来获取:

 

var MyClass = instance.web.Class.extend({

    say_hello: function() {

        console.log("hello", this.name);

    },

});

var my_object = new MyClass();my_object.name = "Sam";my_object.say_hello();// Console打印 "hello Sam"

 

 

 

 

 

 

类可以通过定义init()方法提供初始值设定项来执行实例的初始设置。初始值设定用new运算符传递参数:

 

var MyClass = instance.web.Class.extend({

    init: function(name) {

        this.name = name;

    },

    say_hello: function() {

        console.log("hello", this.name);

    },

});

var my_object = new MyClass("Sam");my_object.say_hello();

// Console 中打印"hello Sam"

 

 

还可用 :func:`~odoo.web.Class.extend` 来创建子类

var MyChineseClass = MyClass.extend({

    say_hello: function() {

        console.log("hola", this.name);

    },

});

var my_object = new MyChineseClass("Sam");my_object.say_hello();

// Console Log 中打印 "hola Sam

当使用继承重写方法时,可以使用 _super()

var MyChineseClass = MyClass.extend({

    say_hello: function() {

        this._super();

        console.log("translation in Chines: 你好", this.name);

    },

});

var my_object = new MyChineseClass("Sam");

my_object.say_hello();

// Console Log中打印 "hello Sam \n translation in Chinese: 你好 Sam"

 

注意:

_super 不是标准方法,如果有,它将被动态设置为当前继承链中的下一个方法。

 

// 错误, 会生成报错

say_hello: function () {

    setTimeout(function () {

        this._super();

    }.bind(this), 0);

}

// 正确

say_hello: function () {

    // 不要忘记 .bind()

    var _super = this._super.bind(this);

    setTimeout(function () {

        _super();

    }.bind(this), 0);

}

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部