【本系列内容直达:】
[手把手带你学习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中如何使用。
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`
`
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示例:
__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"?>
<t t-name="owl_demo" owl="1">
<t t-esc="state.title"></t>
</t>
当然你也可以不需要创建模板文件,在执行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的方式就是命令式的,一步步的告诉浏览器该如何将数据渲染上去,
我们首先需要声明一个变量,声明变量并渲染,
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是odoo贴合自己本身开发的,所以owl也是使用的qweb的语法,这里有个小的弹窗案例,
1.首先创一个owl的弹窗主体内容的xml(我这里交owl_components.xml,为后面的多组件做准备)
<t t-name="owl_confirm" owl="1">
确定
取消
</t>
<t t-name="owl_radios" owl="1">
測試
</t>
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技术交流群。