odoo 自定义 widgets (二)

大家好,

在上一章节的教程中,我们讲了Odoo Widget 【挂件】的基础。包括,基础方法和他们的用途。这一节,我们要做的事情,是学会如何应用这些方法到实际使用当中。

首先,我们都知道在编写odoo 的视图xml时,通过在字段中,添加 widget 标签属性即可渲染出相对应的视图。

例如: 时间挂件 ,可以将时间字段渲染成如图所示的效果。

<field name="myfield" widget="timedate"/>

那我们就来具体阐述一下,这个时间挂件所实现的机制和代码编写逻辑。

# 步骤一:
我们需要新建一个模块,命名它为timepicker。文件结构目录如下:【可以用scaffold先创建一个骨架,再进行修改】

# 步骤二:
修改 _manifest_.py,添加相关依赖。

# 步骤三:

我们来看看widget.js
同所有 widget 一样,第一步定义:

odoo.define('web_widget_timepicker', function (require) {
            "use strict";

 var core = require('web.core');
 //web.core是引用web包的core包
           
 var formats = require('web.formats'); 
 //引用web 包中的formats,odoo的js中预制了一部分formats,提供给大家使用

 var common = require('web.form_common');
//引用web 包中的common类,一些基础方法的引用

# 步骤四:定义widgets:

varTimeDateField = common.AbstractField.extend(common.ReinitializeFieldMixin, {

        //这里的ReinitializeFieldMixin 是最基础的挂件Mixin【其实就是类,js版本的类换汤不换药】

is_field_number: true,

//不做解释,一看就懂

template: "TimeDateField",

// 调用TimeDateField ,它被定义于 

internal_format: 'float_time',

//不做解释,一看就懂

widget_class: 'o_form_field_time',

//此项,在模块中的/src/css里面定义

events: {

        'change input': 'store_dom_value', // store_dom_value 被定义在下方
    },   

//事件,是事件选择器(事件名称和由空间分隔的CSS选择器)映射到回调的方法上。回调既可以是控件中的方法名,也可以是函数。一般是指在发生事件的时候,会触发动作。
// 常见的事件还有 'click p.oe_some_class a': 'some_method',

init: function (field_manager, node) {

this._super(field_manager, node);

// field_manager是用来抓取用户输入值的方法,被定义在web.core里面。因为我们的挂件会修改此方法,将输入从原始的录入变为选填。

this.internal_set_value(0);

//如果,没有值,则设置为0

this.options = _.defaults(this.options, {
                step: 15,
                selectOnBlur: true,
                timeFormat: 'H:i',
                scrollDefault: 'now',
            });  },

// 一些基本设置,提交给jQuery用的,在initialize_content 中被调用

initialize_content: function() {
            if(!this.get("effective_readonly")) {
                this.$el.find('input').timepicker(this.options);
                this.setupFocus(this.$('input'));
            }
        },

// 初始化内容,对本实例中的el(元素)执行.timepicker方法,并带入options

is_syntax_valid: function() {
            if (!this.get("effective_readonly") && this.$("input").size() > 0) {
                try {
                    this.parse_value(this.$('input').val(), '');
                    return true;
                } catch(e) {
                    return false;
                }
            }
            return true;
        },
is_false: function() {
           return this.get('value') === '' || this._super();
       },

//检查,是否有填写错误

focus: function() {
            var input = this.$('input:first')[0];
            return input ? input.focus() : false;
        },

//焦点事件,只有当点击为焦点后才执行

set_dimensions: function (height, width) {
           this._super(height, width);
           this.$('input').css({
               height: height,
               width: width
           });
       },

//设置输入框的宽度和高度

store_dom_value: function () {
            if (!this.get('effective_readonly')) {
                this.internal_set_value(
                    this.parse_value(
                        this.$('input').val(), ''));
            }
        },

//保存用户在前端所选择的数据至数据库中

parse_value: function(val, def) {
            return formats.parse_value(val, {"widget": this.internal_format}, def);
        },

//解析填写进入的数据,在store_dom_value前会调用此方法,以免存的数据格式错误或者其他问题

format_value: function(val, def) {
            return formats.format_value(val, {"widget": this.internal_format}, def);
        },

//重新格式化内部出现的数据,在render_value 渲染数据前,需要先调用此方法,避免

render_value: function() {
  var show_value = this.format_value(this.get('value'), '');

   if (!this.get("effective_readonly")) {
                this.$input = this.$el.find('input');
                this.$input.val(show_value);
            } else {
                this.$(".o_form_time_content").text(show_value);
            }
        },
    });

//渲染最终数据

core.form_widget_registry.add('timepicker', TimeDateField);

// 将'timepicker' 注册到 widget_registry中(挂件注册表)

return {
      TimeDateField: TimeDateField,
  };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值