相关文章推荐
谦虚好学的脸盆  ·  how to remove error ...·  11 月前    · 
坏坏的路灯  ·  c# - ASP.NET MVC + ...·  1 年前    · 

本系列内容直达:
[手把手带你学习Odoo OWL组件开发(1):认识 OWL]
[手把手带你学会Odoo OWL组件开发(2):OWL的使用]
[手把手带你学会Odoo OWL组件开发(3):核心内容指南]
[手把手带你学会Odoo OWL组件开发(4):OWL组件]
[手把手带你学会Odoo OWL组件开发(5):浅析OWL原理]
[手把手带你学会Odoo OWL组件开发(6):API]
[手把手带你学会Odoo OWL组件开发(7):OWL项目实战使用]

本篇内容:OWL的使用

odoo中使用owl

什么是声明式渲染?

owl的声明式是什么样的呢?

为什么前端主流框架都是声明式的渲染方式?

弹窗案例(owl)

上一篇我们对odoo owl做了一个简单介绍,从本篇开始我们将手把手教你如何通过owl开发odoo项目,今天我们通过一个简单的“hello world”示例来看下owl 在odoo中如何使用。

odoo中使用owl

1.首先创建一个father.js文件,然后创建一个templates.xml文件,并且清单文件__manifest__.py中引用templates.xml文件,

demo.js示例:

odoo.define('owl_demo_view', function (require) {
    //必须引入部分
    const { Component, useState ,hooks} = owl;
    const { xml } = owl.tags;
    const { useRef, onMounted, onWillStart} = hooks;
    const {ComponentWrapper} = require("web.OwlCompatibility");
    //qweb,单页面渲染引入部分
    var core = require('web.core');
    var AbstractAction = require('web.AbstractAction');
    //创建元素并展示
    class Parent extends Component {
        //static template = 'owl_demo' //方案一 xml綁定
        //方案二 xml,编写
        static template = xml`
                <div calss="owl-father">
                    <t t-esc="state.title"></t>
                </div>`
        setup() {
            this.state = useState({
                title:'Hello World'
    //实例化qweb页面
    var test_owl = AbstractAction.extend({
        start: function () {
            self = this
            $(document).ready(function () {
                for(const element of self.el.querySelectorAll(".o_content")){
                    //创建实例并挂载到对应元素中
                    (new ComponentWrapper(self, Parent)).mount(element);
            //第二种实例化挂载方式
            const app = new Parent();
            console.log(app,'owl实例')
            //挂载在页面的那个位置 ,这里的document.body是可以换的
            for(const element of self.el.querySelectorAll(".o_content")){
                    //创建实例并挂载到对应元素中
                    app.mount(element);
    core.action_registry.add('owl_demo_view', test_owl);
    return test_owl

templates.xml示例:

<?xml version="1.0" encoding="utf-8"?>
    <template id="aa" name="FrStorageExtendReportKanBanExtend" inherit_id="web.assets_backend">
        <xpath expr="script[last()]" position="after">
            <script type="text/javascript" src="/xc_quotation/static/src/js/demo.js"/>
        </xpath>
    </template>
</odoo>

__manifest__.py示例:

'data': [  
     'views/templates.xml',
'qweb': [  
    'static/src/xml/demo.xml',

2.创建一个模板xml文件,我这里创建的是demo.xml

这里的xml文件就是你想要渲染的东西, 其中t-name是对应js中渲染实例需要的模板名称,是唯一的,不然浏览器会不知道渲染那个模板,同时这里模板通过demo.js关联后就能拿到类中的数据。

?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
     &lt;t t-name="owl_demo" owl="1">
         <div calss="owl-father">
           &lt;t t-esc="state.title">&lt;/t>
     &lt;/t>
 </templates>

当然你也可以不需要创建模板文件,在执行js中编写template也是可以的,这里和vue中的jsx,都是一样的,在demo.js中有讲解。

demo.js中单页需要使用到core,和AbstractAction所以必须引入 var core = require('web.core'); 和var AbstractAction = require('web.AbstractAction');

在odoo中你想创建一个单页,是必须通过odoo已有的模块来完成的,必须将类通过命名的方式,注册到odoo中,不然是没办法渲染,并拿到页面的,

这样注册后,odoo中的菜单, menuitem 和action跳转到这个挂载的页面。

这里的 name=“tag”标签中的owl_demo_view,是需要和core.action_registry.add('owl_demo_view', test_owl);这个名字是一样的,odoo才能获取到对应的页面,然后你点击菜单的时候就会渲染

这里可以看到t-sec="state"是直接可以获取js中的数据的,通过关联实例 template "owl_demo_father",

这里是通过申明式的渲染方式,将hello world渲染到t标签中。

什么是声明式渲染?

我的理解就是,声明一个变量,并且能直接获取并渲染到页面模板中。

比较官方的说法是:声明式:只告诉程序想要什么结果,如何达成由程序完成,开发者不用关心。

声明式渲染实现的是,DOM 随状态(数据)更新而更新。

而对应的就是有命令式: 一步一步告诉程序如何去做,能否达成结果取决于开发者的设计。

jq的直接操作dom的方式就是命令式的,一步步的告诉浏览器该如何将数据渲染上去,

owl的声明式是什么样的呢?

我们首先需要声明一个变量,声明变量并渲染,

1,声明一个app的常量,并通过新建一个类,

const app = new Parent();

2,挂载 并实例化这个类,

app.mount(document.body);
 console.log(app,'owl实例')

为什么前端主流框架都是声明式的渲染方式?

在VUE和React中都是声明式的渲染方式,为什么呢,因为这样,编写的代码会更少,逻辑和渲染会分离开来,更容易读懂,和拓展。

下面我打印了app这个实例,一起来看看实例中有哪些东西吧,简单的实例当然就是你new class的集合里面的数据,方法, 在这些的同时,owl也封装了一些odoo自有的方法到owl中,这些会在后期与大家讲解。

这里可以打印这个app 可以看到里面的实例化数据, 如果我在这个时候去操作修改声明的变量也是可以的

app.data.Name='声明变量修改后'

可以看到这里的这个展示的也会同步修改,

当然不建议这样修改,建议通过方法去修改变量,这也是大家常做的方式。

弹窗案例(owl)

因为owl是odoo贴合自己本身开发的,所以owl也是使用的qweb的语法,这里有个小的弹窗案例,

1.首先创一个owl的弹窗主体内容的xml(我这里交owl_components.xml,为后面的多组件做准备)

<?xml version="1.0" encoding="utf-8" ?>
<templates xml:space="preserve">
     &lt;t t-name="owl_confirm" owl="1">
             <div class="owl-popup-mask"></div>
            <div class="owl-confirm-xl" id="owlConfirm">
                <div class="owl-confirm-title">
                   <p t-esc="state.title" class="owl-confirm-text"></p>
                    <div class="owl-confirm-btn">
                    <div t-on-click="confimrBtn" class="btn btn-primary">确定</div>
                        <div t-on-click="closeConfim" class="btn  btn-white  ml20">取消</div>
     &lt;/t>
    &lt;t t-name="owl_radios" owl="1">
         <div calss="owl-radios">
     &lt;/t>
 </templates>

2.创建对应xml组件的owl_components.js文件同样需要引入到清单文件__manifest__.py和template.xml中

owl_components.js示例:

odoo.define('owl_components', function (require) {
    "use strict";
    const { Component, useState ,hooks} = owl;
    const { xml } = owl.tags;
    const { useRef, onMounted, onWillStart} = hooks;
    const {ComponentWrapper} = require("web.OwlCompatibility");
    class OwlConfirm extends  Component{
        static  template= "owl_confirm";
        setup() {
            this.state = useState({ title: "測試",
                row:this.__owl__.parent.parentWidget.recordData
            this.state.title = 'xxxxxxxx内容部分'
        confimrBtn(url){
            console.log(this.state.row,'确定');
            let self = this;
            let paramsData = {
                    id:(this.state.row.id).toString()
            console.log(this,'aaaaasss')
            console.log(this.env,'ssss')
            this.rpc({
                route: 'xxxxx/xxxxx',
                params: paramsData
            }).then(res=>{
                console.log(res,'sss')
                this.env.services.notification.notify({
                    title:'系统提示',
                    message: res['msg'],
                    type: 'success',
                // self.destroy();
        closeConfim(){
             this.destroy();
    class  OwlRadios extends  Component{
         static  template= "owl_radios";
    return  {
        OwlConfirm,
        OwlRadios

这里直接return两个类,然后再你需要使用的页面,对应位置实例化挂载这个类

//需要引入的两个模块
const {ComponentWrapper} = require("web.OwlCompatibility");//实例化模块
const {OwlConfirm  }=  require('owl_components');//组件模块
然后我这里是点击后渲染
//修改数据
editRows: function (){
    (new ComponentWrapper(this, OwlConfirm)).mount(document.body);

css样式

/*弹窗*/
.owl-confirm-xl{
    width: 400px;
    height: 200px;
    padding: 20px;
    position: fixed;
    top: 50%;
    left:50% ;
    transform: translateX(-50%);
    background-color: #fff;
    z-index: 999;
    border-radius: 5px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
.owl-confirm-title{
    flex: 1;
.owl-confirm-btn{
    height: 30px;
    display: flex;
    justify-content: flex-end;
.owl-confirm-text{
    font-size: 22px;
    text-align: center;
.owl-popup-mask{
    display: block;
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    opacity: 0.5;
    background: #000000;
    z-index: 998;


版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。

公众号搜索神州数码云基地,后台回复Odoo,加入Odoo技术交流群。

上一篇我们对odoo owl做了一个简单介绍,从本篇开始我们将手把手教你如何通过owl开发odoo项目,今天我们通过一个简单的“hello world”示例来看下owl 在odoo中如何使用。odoo中使用owl1.首先创建一个father.js文件,然后创建一个templates.xml文件,并且清单文件__manifest__.py中引用templates.xml文件,demo.js示例:odoo.define('owl_demo_view', function (require) {