发现一odoo学习好资料
作者:互联网
第一章 OWL简介
OWL是什么
OWL(Odoo Web Libary)是Odoo从14.0开始引入的前端框架, OWL区别于之前版本的QWeb技术, 与近些年来前端流行的框架(React, Vue, Angular, Backbone)更为相似. 如果你对现在的这些流行的前端框架有所了解,那么你一定明白这些框架的目的都在于简化之前那些由javascript来处理的琐碎的工作. 这些框架最大程度地解耦了你的HTML和Javascript代码, 动不动写几百行代码用来操作HTML DOM元素与监听事件的时代成为了过去式.
举个非常简单的例子,我们这里都有一段HTML代码:
<button id="countButton">Increment Count</button>
<button id="clearButton">Clear Count</button>
<div id="results">0</div>
这段代码定义了2个按钮,一个用来增加计数, 一个用来归零. 如果用我们过去的代码方式, 这段代码应该这么写:
// ew, gross
const clicks = 0;
const countButton = document.querySelector("#countButton");
myButton.addEventListener("click", function() {
clicks += 1;
const results = document.querySelector("#results");
results.innerHTML = clicks;
});
const clearButton = document.querySelector("#clearButton");
clearButton.addEventListener("click", function() {
clicks = 0;
const results = document.querySelector("#results");
results.innerHTML = click;
});
这只是一小段代码, 随着项目量的增长, 这些代码的可读性将变得很差. 现在, 让我们来看一下现代框架们是如何处理的(OWL为例):
<button id="countButton" t-on-click="state.count++">Increment Count</button>
<button id="clearButton" t-on-click="state.count = 0">Clear Count</button>
<div id="results" t-esc="state.count"/>
const { Component, useState } = owl;
class ClickComponent extends Component {
state = useState({ count: 0 });
}
DOM操作和事件监听完全由框架来帮我们处理了, 代码变得非常简单.
Odoo为啥创建了OWL而没有使用React, Vue等既有框架?
哈, 这个可以看官方的回答
在笔者看来无非就两个原因, 一是现有框架不能完全满足Odoo的需求, 二是作为一个帮技术控,有足够的自信自己做一套出来, 同时也不想被其他框架制约.
主要特点
与旧框架相比,OWL香在以下几点, 写起来更简单, 更优雅, 可读性也更高.
生命周期的组件
在过去, 我们需要监控DOM的状态,以防止我们的代码运行时符合预期. 而现在, 我们知道我们的组件会在页面启动时加载, 在页面跳转时消亡, 而且我们有很多钩子用来处理这些事情, 而不再有$(document).ready了.
响应式虚拟DOM
如果你看了前面的代码, 那么你就看到了响应式绑定的好处, 我们只需要考虑如何组织处理数据, 而不用再关心如何操作处理DOM元素, 所有的DOM操作代码都被移除了,当我们的数据发生变化时, 页面自动进行了更新. 很多现代框架都提供了虚拟DOM用来跟踪前端结构发生的变化, 尤其是事件绑定的场景.
更好的可读性
移除了操作DOM的代码之后, 代码的可读性自然就提高了, 而且我们更容易把精力放到项目本身的逻辑处理中,对于编写测试脚本和测试用例来说显然也变得更容易.
开始学习
虽然OWL在15.0发布时又发生了变化, 但是我们的学习还是从14.0时开始, 下面的例子即基于odoo14.0, 后面我们会介绍15.0究竟与14.0有何不同.
我们依旧使用我们的书店模块, 这次主要工作在static/src/js目录中, 我们创建一个新文件夹components用来存放我们的组件代码.
OWL通过定义组件(Component)来渲染模板,加载数据, 加载子组件等工作. 在HTML中, 我们有header, div, span, textarea等标签来供我们使用, 当我们要创建一个OWL组件时,我们需要思考,当我们创建了这个组件,对我们的项目有什么好处.
本例子中,我们将创建一个组件用来显示销售单下的某个客户的订单历史信息.
创建和注册js类
我们在components文件夹下创建一个PartnerOrderSummary.js文件.
odoo.define("book_store.PartnerOrderSummary", function (require) {
'use strict';
const { Component } = owl;
class PartnerOrderSummary extends Component {
};
Object.assign(PartnerOrderSummary,{
template: "book_store.PartnerOrderSummary"
});
});
跟14.0之前的版本一样, 所有的js文件都要在templates文件中注册到assets中:
<template id="assets_backend_book_store" inherit_id="web.assets_backend" name="book_store">
<xpath expr="script[last()]" position="after">
<script type="text/javascript" src="/book_store/static/src/js/component/PartnerOrderSummary.js"></script>
</xpath>
</template>
为component创建模板
现在我们来为我们的组件创建一个模板文件(同样位于components文件夹内):
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="book_store.PartnerOrderSummary" owl="1">
<div>My cool new widget</div>
</t>
</templates>
同样的,我们需要把模板文件放到QWeb中
"qweb":[
"static/src/js/components/PartnerOrderSummary.xml"
],
在销售单中显示组件
现在我们需要把我们的组件显示到销售单中, 首先,我们需要更新我们的依赖:
'depends': ['sale_management'],
重载表单的渲染方法挂载我们的组件
想要在销售单中显示我们的组件,最简单的办法就是重载表单的渲染方法, 下面我们将修改PartnerOrderSummary.js的文件内容:
odoo.define("book_store.PartnerOrderSummary", function (require) {
'use strict';
const FormRenderer = require("web.FormRenderer");
const { Component } = owl;
class PartnerOrderSummary extends Component {
};
Object.assign(PartnerOrderSummary, {
template: "book_store.PartnerOrderSummary"
});
FormRenderer.include({
async _render() {
await this._super(...arguments);
for (const element of this.el.querySelectorAll(".o_partner_order_summary")) {
(new ComponentWrapper(this, PartnerOrderSummary))
.mount(element)
}
}
});
});
如果你没有涉足过odoo的前端开发,那么这段代码来说阅读起来可能有点困难, 不过没关系, 我们只要知道通过ComponentWrapper, 我们可以在把要一个组件挂载到任何元素上.
(new ComponentWrapper(this, PartnerOrderSummary))
.mount(element)
添加div元素到销售单表单视图
从上面的代码中我们可以看到,要显示的组件需要定位到含有o_partner_order_summary样式的div标签上, 因此,接下来我们添加这个标签:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sale_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="payment_term_id" position="after">
<div class="o_partner_order_summary" colspan="2"/>
</field>
</field>
</record>
</odoo>
然后把我们的视图文件放到_mainfest_.py文件中:
'data': [
'security/ir.model.access.csv',
'views/views.xml',
"views/sale.xml"
]
标签:OWL,const,PartnerOrderSummary,代码,odoo,学习,资料,组件,我们 来源: https://blog.csdn.net/fqfq123456/article/details/123186632