Odoo的网页模块QWEB简述Word文档下载推荐.docx
- 文档编号:16211306
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:13
- 大小:21.63KB
Odoo的网页模块QWEB简述Word文档下载推荐.docx
《Odoo的网页模块QWEB简述Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Odoo的网页模块QWEB简述Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
行调试开发了。
在前面的章节中,我们解释了JavaScript缺少命名空间机制,来分割在不同的JavaScript文件中声明的变量。
并且我们提出了模块模式这个简单方法。
模块模式(如app.js文件):
(function(){
app={};
function
main(){
console.log("
launchapplication"
);
};
app.main=main;
})();
在OpenERP的web框架内,有个类似于模块模式的等价物,集成了该框架的其余部分。
请注意,OpenERP的Web模块与其他OpenERP的addon模块概念上是不同的,一个addon模块是一个包含很多文件的文件夹,web模块仅仅是一个有命名空间概念的JavaScript。
1)模块
oepetstore/static/js/petstore.js声明了这样的模块:
openerp.oepetstore=function(instance){
instance.oepetstore={};
instance.oepetstore.XXX=......;
}
在OpenERP的Web框架内,通过声明一个函数来声明一个JavaScript模块,并把这个函数放在全局变量openerp的属性内.这个属性名称必须和OpenERPaddon模块名称一致(这addon模块名为oepetstore,我应把函数赋值给openerp.oepetstore属性。
如果换成openerp.petstore属性,则无法正常运行)。
当Web客户端转载这个addon模块时,该函数将被调用。
将传入一个名为instance的参数,这个参数代表当前OpenERP的Web客户端实例,包含了所有相关当前会话数据,以及所有Web模块的变量。
在instance对象内创建与addon模块名称一致的新命名空间是个惯例。
这就是为什么我们在instance.oepetstore设置一个空dictionary。
这个dictionary就是命名空间,用来声明我们模块内自己使用的所有类和变量。
2)类
JavaScript不像其他面向对象编程语言那样有类机制。
更确切地说,它提供了面向对象编程语言元素,但你必须自己定义,自己选择如何做。
OpenERP
Web框架提供工具来简化这个过程,让程序员以类似其他编程语言,如Java的方式编码。
定义一个新类,你需要从instance.web.Class类继承。
语法如下:
instance.oepetstore.MyClass=instance.web.Class.extend({
say_hello:
function(){
hello"
},
});
类的实例化:
varmy_object=newinstance.oepetstore.MyClass();
my_object.say_hello();
类可以有一个构造函数,它方法名为init()。
你可以像大多数开发语言那样,传递参数给构造器:
init:
function(name){
this.name=name;
this.name);
类的继承
类可以被继承
instance.oepetstore.MySpanishClass=instance.oepetstore.MyClass.extend({
this._super();
hola"
var
my_object=new
instance.oepetstore.MySpanishClass("
Nicolas"
this._super()不是常用的类方法
3)WidgetsBasics(基础部件)
OpenERP中Widget部件,是一个通用组件,专门用来向用户显示内容。
oepetstore实例中的petstore.js内容:
var_t=instance.web._t,
_lt=instance.web._lt;
QWeb=instance.web.qweb;
<
!
--部件-->
instance.oepetstore.HomePage=instance.web.Widget.extend({
start:
petstorehomepageloaded"
instance.web.client_actions.add('
petstore.homepage'
'
instance.oepetstore.HomePage'
最后一行代码,把这个部件注册为客户端的action。
当我们点击‣PetStore‣PetStore‣Home
Page菜单项时,客户端action让部件显示出来。
HomePage部件有一个start()方法。
在部件初始化后,这方法被自动调用。
它已接接受指令去显示其内容。
我们将用它向用户显示一些内容。
要做到这一点,我们使用所有部件都有的$el属性。
该属性是一个jQuery对象,表示部件对应的HTML标签的根标签。
部件包含了多个HTML标签,这些HTM标签有一个统一的根标签。
默认情况下,部件都有一个空的根标签:
一个<
div>
。
HTML标签在没有具体内容的时候,是不可见的。
这也解释了为什么显示instance.oepetstore.HomePage时,是个空白区域,它根本没有任何内容。
要想显示些内容,我们用jQuery该对象上的一些简单方法,在根标签中添加一些HTML标签:
this.$el.append("
HellodearOpenERPuser!
/div>
"
常用方法:
appendTo()方法
pettoys=new
instance.oepetstore.PetToysList(this);
//实例化PetToysList()部件
pettoys.appendTo(this.$("
.oe_petstore_homepage_left"
));
//把pettoys添加到当前部件的class=.oe_petstore_homepage_left的标签中
注意:
new
instance.oepetstore.PetToysList(this),其中参数this,代表调用此部件的实例,表示部件的隶属关系。
addClass()方法
this.$el.addClass("
oe_petstore_homepage"
//添加样式
getParent()方法
用于获取父部件
getChildren()方法
用来获取子部件列表:
this.getChildren()[0].$el
当你在部件中重载init()时,必须以父部件作为第一参数传入,并调用传入给this._super(),例如:
instance.oepetstore.GreetingsWidget=instance.web.Widget.extend({
function(parent,name){
this._super(parent);
最后,如果一个部件没有父部件(即:
在你的应用实例化时是第一个部件),传入null参数:
newinstance.oepetstore.GreetingsWidget(null);
销毁部件:
destroy()方法:
当一个部件被销毁,它会先调用所有子部件的destroy()。
然后,它在DOM中清楚自己。
通过部件隶属关系的递归调用,避免了内存泄漏,这对容易产生内
存泄露的大型JavaScript应用程序来说是非常有用的。
2.Qweb
在OpenERP中,使用Qweb模板引擎,专门用于Web客户端开发。
Qweb是一种基于XML的模板语言,类似Genshi,Thymeleaf或Facelets。
有如下几个特点:
①在浏览器中完全用JavaScript执行。
②每个模板文件(XML文件)包含了多个模板,而其他模板引擎通常做法是,模板文件和模板之间1:
1的关系。
③在OpenERP的Web的instance.web.Widget特别支持了QWeb。
虽然QWeb可以用于OpenERP的Web客户端以外的地方(同时instance.web.Widget也可以不依赖于Qweb)。
之所以没用用其他JavaScript模板引擎,而是选择了QWeb,是因为QWeb的扩展机制与OpenERP的视图继承机制很相似。
就像OpenERP的视图一样,QWeb模版也是个XML树结构,因此很容易在模版执行XPath或DOM操作。
在部件内使用QWeb
首先,在文件oepetstore/static/src/xml/petstore.xml里我们定义一个简单的QWeb模板。
?
xml
version="
1.0"
encoding="
UTF-8"
>
templates
xml:
space="
preserve"
t
t-name="
HomePageTemplate"
div
style="
background-color:
red;
ThisissomesimpleHTML<
/t>
/templates>
现在,修改HomePage类:
我们建议在所有的OpenERPweb模块复制粘贴这行代码。
这个对象提供访问被Web客户端加载的所有模版文件中的模版的功能。
下面是我们使用XML模板文件定义的模版的例子:
this.$el.append(QWeb.render("
解释:
QWeb.render()方法用来渲染指定标识名称的具体模版,第一个参数就是模版标识名称。
另外一个常用地方是,在部件内集成Qweb:
template:
...
当你在部件内设置类属性template时,部件就知道它需要调用QWeb.render()来呈现该模板。
请注意这两个语法是有区别的。
当在部件内集成Qweb时,QWeb.render()调用在部件调用start()之前发生,并用模版的根标签替换了部件的默认根标签。
这会导致不同的结果,所以你应该记住它。
Qweb上下文(Context)
像所有的模板引擎一样,Qweb模板可以包含操纵传递给模板的数据的代码。
1)使用QWeb.render()的第二个参数传递数据给模版:
Hello<
t-esc="
name"
/>
QWeb.render("
{name:
输出结果:
HelloNicolas<
2)当部件整合QWeb时,就不能直接传入数据了。
替换办法是,模板有一个唯一变量widget,这个变量引用了当前部件:
function(parent){
this.name="
;
模版声明
Qweb的语法:
Qweb指令使用前缀t-的XML属性来声明新模板,我们在XML文件的根元素<
template>
内添加一个<
tt-name="
..."
元素:
templates>
Escaping————转义
用t-esc:
在HTML中放置文本
这将输出变量name,并转义变量的上下文,这上下文也许是类似HTML的字符串。
请注意,该属性t-esc可包含各种JavaScript表达式:
3+5"
输出HTML
如果你明确知道变量会包含一些HTML标签,使用t-raw代替的t-esc:
t-raw="
some_html"
条件
QWeb的条件关键字是t-if:
t-if="
true==true"
trueistrue
true==false"
trueisnottrue
Qweb条件分支没有“else”这个分支结构。
循环
遍历列表,使用t-foreach和t-as
t-foreach="
names"
t-as="
设置任意XML属性值
Qweb有一个特定语法设置属性值。
您必须使用t-att-xxx并用属性名替换xxx:
Inputyourname:
input
type="
text"
t-att-value="
defaultName"
3.部件事件和属性
1)事件
部件类似现有大部分图形用户界面库(Qt,GTK,Swing,...)那样,触发事件,
处理事件。
例如:
instance.oepetstore.ConfirmWidget=instance.web.Widget.extend({
self=this;
Areyousureyouwanttoperformthisaction?
+
buttonclass='
ok_button'
Ok<
/button>
cancel_button'
Cancel<
this.$el.find("
button.ok_button"
).click(function(){
self.trigger("
user_choose"
true);
button.cancel_button"
false);
widget=new
instance.oepetstore.ConfirmWidget(this);
widget.on("
this,this.user_choose);
widget.appendTo(this.$el);
user_choose:
function(confirm){
if(confirm){
Theuseragreedtocontinue"
}else{
Theuserrefusedtocontinue"
请记住,在JavaScript中,变量this会隐含传递给所有函数。
如果函数像对象引用方法那么用,通过this我们知道当前的对象是什么。
每个已声明的函数都有自己的this。
所以,当我们在一个函数内声明了另一个函数,这个新功能将有自己的this,这和父函数this含义不同。
如果我们要用原来的对象this,最简单的方法是把引用存储在一个本地变量。
在OpenERP内,按照Python的习惯,通常该变量命名为self。
由于这个部件应该是通用的,它本身不应执行任何具体action。
所以,我们用trigger()方法设置了名字叫"
的触发器和事件。
Widget.trigger(event_name[,...])方法的第一个参数是待触发的事件名,也接受任何数量的其他参数。
这些参数将被传递到所有的事件侦听器。
然后,我们修改部件HomePage去实例化一个部件ConfirmWidget,通过on()方法监听"
事件。
Widget.on(event_name,object,func)允许绑定一个事件event_name触发时调用的函数func。
如果func是个方法,则object是func函数的引用关联对象。
当func被调用时,trigger()的其他参数会传递给它。
widget=...
my_event"
this,this.my_event_triggered);
widget.trigger("
1,2,3);
my_event_triggered:
function(a,b,c){
console.log(a,b,c);
//willprint"
123"
2)属性
属性类似与普通对象的属性。
可以在对象上设置数据,但有个额外的功能:
属性值改变时将触发事件。
this.widget=...
this.widget.on("
change:
this,this.name_changed);
this.widget.set("
"
name_changed:
Thenewvalueoftheproperty'
name'
is"
this.widget.get("
Widget.set(name,value)方法设置某个属性的值。
如果该值改变(或以前没有值),对象将触发一个事件change:
xxx。
xxx是属性名称。
4.部件辅助工具
1)部件的jQeruy选择器
find()方法
input.my_input"
)
$()方法
this.$("
说明:
我们强烈建议你也不要使用,全局jQuery函数$()。
这种全局选择器满足简单应用,但在真正的大型web应用程序中不好。
原因很简单:
当你创建一个新部件,你永远不知道它会实例化多少次。
由于$()全局函数是操作浏览器中的全部HTML,如果你实例化一个部件两次,该函数会搞混两个部件的个内容。
这就是为什么,大部分时间里,你在定位部件里的HTML时,必须限制jQuery选择器的选择范围。
出于同样的逻辑,你也可以猜测到,不能够在部件里使用HTMLid。
如果widget被实例化的两次,在应用程序里将有两个相同id,但却是不同的HTML元素的情况。
而这本身就是一个错误。
所以,在所有的情况下,你应该坚持使用用CSS类去标记HTML标签。
2)简易DOM事件绑定
在前面的一部分,我们必须用click()或change()等事件绑定HTML元素。
现在,我们用$()来简化代码,让我们看看如何做:
instance.oepetstore.MyWidget=instance.web.Widget.extend(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Odoo 网页 模块 QWEB 简述