odoo前端开发widget

重要信息:Odoo
14与此前的Odoo版本在网页客户端上有些特别之处。它包含了两套框架用于维护Odoo后台的图形界面。第一种是传统的基于微件(小部件)的框架,第二种是基于模块化的现代框架,称之后Odoo网页库(OWL)。OWL是在Odoo
v14中新引入的UI框架。两者都使用QWeb模块作为结构,但在语法及框架运行方式上做出了很大的改变。

虽然Odoo
14使用了新框架OWL,但Odoo并没有在处处使用它。大多数网页客户端仍然使用老的基于微件的框架。本章中,我们将学习如何自定义基于微件框架的网页客户端。下一章中我们会学习OWL框架。

本章中,我们将学习如何创建新字段微件来获取用户输入。我们还将从零开始新建视图。在阅读完本章后,读者将能够在Odoo后台中创建自己的UI元素。

**注:**Odoo
的用户界面重度依赖于JavaScript。在本章中我们会假定你已具备JavaScript、jQuery、Underscore.js和SCSS的基础知识。

本章中,我们将讲解如下小节:

  • 创建自定义微件
  • 使用客户端QWeb模板
  • 向服务端做RPC调用
  • 新建一个视图
  • 调试客户端代码
  • 通过引导提升用户上手体验
  • 移动应用JavaScript

标题技术准备

学习本章要求已经有一个Odoo在线平台。

本章中的所有代码可通过GitHub仓库进行下载。

标题创建自定义微件

在第九章 后端视图中已经学到,我们可以使用微件来以不同格式展示某些数据。例如,我们使用了widget='image’将二进制字段展示为图片。要演示如何创建自己的微件,我们将编写一个用户可以选择整型字段的微件,但我们将采用不同的展现方式。使用的不是输入框,而是展示为颜色拾取器,这样我们我们可以选择颜色数值。这里的数值与相关的颜色存在映射关系。

准备工作

本节中我们将使用带有基础字段和视图的my_library模块。在GitHub仓库的Chapter15/00_initial_module目录下可以找到这一基础my_library模块。

如何实现…

我们将添加包含微件逻辑的JavaScript文件,以及负责样式的SCSS文件。然后,我们在图书表单中添加一个整型字段来使用新微件。按照如下步骤来新增一个字段微件:

  1. 添加一个static/src/js/field_widget.js文件。此处所使用的语法可参见

第十四章 CMS网站开发 中

为网站扩展CSS和JavaScript

一节:

odoo.define('my_field_widget', function (require) {
  "use strict";
  var AbstractField = require('web.AbstractField');
  var fieldRegistry = require('web.field_registry');
  1. 通过继承AbstractField来创建微件:
var colorField = AbstractField.extend({
  1. 设置CSS类、根元素标签以及微件所支持的字段类型:
className: 'o_int_colorpicker',
tagName: 'span',
supportedFieldTypes: ['integer'],
  1. 捕获某些JavaScript事件:
events: {
  'click .o_color_pill': 'clickPill',
},
  1. 重载init进行初始化:
init: function () {
  this.totalColors = 10;
  this._super.apply(this, arguments);
},
  1. 重载_renderEdit和_renderReadonly来设置DOM元素:
_renderEdit: function () {
  this.$el.empty();
  for (var i = 0; i < this.totalColors; i++ ) {
    var className = "o_color_pill o_color_" + i;
      if (this.value === i ) {
        className += ' active';
      }
    this.$el.append($('', {
      'class': className,
      'data-val': i,
    }));
  }
 },
 _renderReadonly: function () {
  var className = "o_color_pill active readonly o_color_" + this.value;
  this.$el.append($('', {
    'class': className,
  }));
 },
  1. 定义我们在前面所使用的handler:
  clickPill: function (ev) {
    var $target = $(ev.currentTarget);
    var data = $target.data();
    this._setValue(data.val.toString());
  }
}); // closing AbstractField
  1. 别忘了注册该微件:
fieldRegistry.add('int_color', colorField);
  1. 让其在其它插件中可使用用:
  return {
  colorField: colorField,
  };
}); // closing 'my_field_widget' namespace
  1. 在static/src/scss/field_widget.scss中添加一些SCSS:
.o_int_colorpicker {
  .o_color_pill {
    display: inline-block;
    height: 25px;
    width: 25px;
    margin: 4px;
    border-radius: 25px;
    position: relative;
    @for $size from 1 through length($o-colors) {
      &.o_color_#{$size - 1} {
        background-color: nth($o-colors, $size);
        &:not(.readonly):hover {
          transform: scale(1.2);
          transition: 0.3s;
          cursor: pointer;
        }
        &.active:after{
          content: "\f00c";
          display: inline-block;
          font: normal normal normal 14px/1 FontAwesome;
          font-size: inherit;
          color: #fff;
          position: absolute;
          padding: 4px;
          font-size: 16px;
        }
      }
    }
  }
}
  1. 在views/templates.xml后台资源中注册这两个文件: