ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

发现一odoo学习好资料

2022-02-28 16:59:21  阅读:195  来源: 互联网

标签:OWL const PartnerOrderSummary 代码 odoo 学习 资料 组件 我们


第一章 OWL概述 · 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有