Odoo 12开发之看板视图和用户端 QWeb

Odoo 12开发之看板视图和用户端 QWeb

前言:

Qweb是odoo使用的模板引擎,基于xml来生成HTML片段和页面.
通过Qweb可生成丰富的看板视图,报表和cmx

一·了解看板

# 两种布局	
	# 1. 卡片列表
	# 2. 组织成不同的卡片	

二·设计看板视图

优先级、看板状态和颜色
# 看版中其他字段:
	priority  #   让用户组织他们的工作项,标记什么应优先处理
	kanban_state  #   标记是否应移向下一阶段或因某种原因原地不动。在模型定义层中两者都是选择项字段。在视图层,对它们有特别的组件用于表单和看板视图。
    color   # 用于存储看板卡片显示的颜色,并可通过看板视图中的颜色拾取器菜单设置
	# 如下例:
    class Checkout(models.Model):
        ...
        priority = fields.Selection(
            [('0', 'Low'),
             ('1', 'Normal'),
             ('2', 'High')],
            'Priority',
            default='1')
        kanban_state = fields.Selection(
            [('normal', 'In Progress'),
             ('blocked', 'Blocked'),
             ('done', 'Ready for next stage')],
            'Kanban State',
            default='normal')   
    
看板卡片元素
# 看板视图框架包含了一个<kanban>外层元素和一下基础结构
# 看板支持属性:
	default_group_by  #  设置默认列分组使用的字段
	default_order  #  设置看板项默认使用的排序
 	quick_create=”false”  #  禁用了每列顶部的快速创建选项(大的加号符号),快速创建只需提供标题描述即可创建新项。false是 JavaScript 的语法,必须是小写字母。
	class  #  为渲染看板视图的根元素添加 CSS 类。相关类是_kanban_small_column,让列比默认的更加紧湊。其它类可由我们模块的 CSS 文件来进行提供。
 	group_create, group_edit, group_delete和quick_create_view   #  可设置为 false 来禁用看板列上对应的操作。如group_create=”false”删除右侧添加新列的按钮。
	on_create  #  用于创建用户点击左上角 Create 按钮时弹出的自定义简单表单视图窗口。应为相应的表单视图添加<module>.<xml_id>值。
    
    
    
    
### <progressbar> 如下属性:
	field	#  是对列中各项进行颜色分组的字段名
	colors	#  是一个字典,将分组字段值与以下三种颜色分别进行映射:danger (红色), warning (黄色)或success (绿色)。
	sum_field	#  是一个可选项,用于选取整列汇总的字段名。如未设置,会使用各项的计数值。
<kanban default_group_by="stage_id" class="o_kanban_small_column">
    <!-- Fields -->
    <field name="stage_id" />
    <field name="id" />
    <field name="color" />
    <field name="kanban_state" />
    <field name="priority" />
    <field name="message_partner_ids" />

    <!-- Optional progress bar -->
    <progressbar
                 field="kanban_state"
                 colors='{"done": "success", "blocked": "danger"}' />
    <!-- Templates with HTML snippets to use -->
    <templates>
        <t t-name="kanban-box">
            <!-- HTML Qweb template -->
        </t>
        </template>
</kanban>

三·Qweb模板语言

# QWeb 会查找模板种的特殊指令,并动态的替换掉生成的HTML.
# 对于使用带有QWeb指令的(t-if t-foreach)的特殊元素.该元祖不会在最终产生的xml/html有任何输出
# QWeb指令常使用运算的表达式生成不同结果:
    # 报表和网页使用服务端QWeb的python实现
    # 看板使用客户端js实现,即看板视图种的QWeb表达式应使用js编写
    
    
### 看板视图 , 内部的步骤流程
	# 1. 获取模板的XML进行渲染
	# 2. 调用服务端read()方法来获取模板中所涉及的字段数据
	# 3. 定位kanban-boxs模板并使用QWeb解析它来输出最终的HTML片断
	# 4. 在浏览器显示(DOM)中注入 HTML
QWeb JavaScript 运行上下文
# QWeb指令使用表达式的运行来生成结果
	raw_value  # 是由服务端read()方法返回的值
	value  # 根据用户设置来格式化
	widget  # 是当前KanbanRecord()组件对象的引用,用于在看板种渲染当前记录
	record # 是 widget.record的简写形式,使用点号标记来提供对可用字段的访问
	read_only_mode # 标识当前视图是否为读模式(非编辑模式)是widget.view.options.read_only_mode的简写形式。
    instance # 是对全部网页客户端实例的一个引用
    
### XML 标准中,这些字符具有特殊含义
    lt是小于
    lte是小于等于
    gt是大于
    gte是大于等于
字符串替换动态属性– t-attf
# t-attf 来作为*<div>元素设置一个类,根据卡片的color字段值来显示颜色
# t-attf 指令查找代码块运行并替换结果,通过{{}} 和#{{}} 来进行分隔. 代码块的内容是任意js表达式,QWeb表达式中的任意可用变量.

# 例子:
	t-attf-class="oe_kanban_text_red" # 显示为红色
	t-attf-class="oe_kanban_text_{{
                  record.priority.raw_value lt '2'
                  ? 'black' : 'red'}}"  # 记录的星星小于2是黑色,否则是红色
<li t-attf-class="oe_kanban_text_{{
                  record.priority.raw_value lt '2'
                  ? 'black' : 'red'}}">
    <field name="user_id" />
</li>
表达式动态属性 t–att–
# t-att- 是QWeb指令通过表达式动态生成的属性值.
# .value字段返回在屏幕上显示的值,鼠标悬停在图像上时就会显示相对于的用户名.
t-att-title="record.member_id.value" 
循环 – t-foreach
# t-foreach 指令接受一个js表达式. 
    t-as  指令设置别名,

### rec 变量
    rec_index是迭代索引,从0开始
    rec_size是集合中的元素数量
    rec_first在迭代的第一个元素中为真
    rec_last在迭代的最后一个元素中为真
    rec_even在索引为偶数时为真
    rec_odd在索引为奇数时为真
    rec_parity根据当前索引为odd或even
    rec_all表示进行迭代的对象
    rec_value在迭代{key:value} 字典时,存储value (rec存储键名)
    
### t-foreach="record.message_partner_ids.raw_value.slice(0, 3)"
	是对取到内容进行了切片
<t t-foreach="record.message_partner_ids.raw_value.slice(0,3)" t-as="rec">
    <img t-att-src="kanban_image('res.partner', 'image_small', rec)"
        class="oe_avatar" width="24" height="24" alt="" />
</t>
条件判断 – t-if
<t t-if="record.num_books.raw_value == 0">
    <li>No books.</li>
</t>
<t t-elif="record.num_books.raw_value gt 9">
    <li>A lot of books!</li>
</t>
<t t-else="">
    <li><field name="num_books" /> books.</li>
</t>
渲染值 t-esc和t-raw
### <field/>元素可以渲染值 t-esc 也可以渲染值, t-raw是确定数据是否安全的渲染值(避免使用)

# t-esc 指令运行表达式并将其渲染为转义后的 HTML 值
	<t t-esc="record.message_partner_ids.raw_value" />
# t-raw 确定源数据是安全的,可以无需转义使用t-raw 来渲染原始值
	<t t-raw="record.message_partner_ids.raw_value" />
为变量设置值 – t-set
# 对于更复杂的逻辑,可以将表达式结果存储在变量中
# t-set指令来实现,设置变量名
# t-value指令来添加表达式计算分配的值
<t t-set="red_or_black"
   t-value="record.priority.raw_value gte '2' ? 'oe_kanban_text_red' :''" />
<li t-att-class="red_or_black">
    <field name="user_id" />
</li>
调用和复用其它模板 – t-call
# 重复调用  , 一句 t-name设置的名字.可重复调用
<t t-name="follower_avatars">
    <div>
        <t t-foreach="record.message_partner_ids.raw_value.slice(0,3)"
           t-as="rec">
            <img t-att-src="kanban_image('res.partner', 'image_small', rec)"
                 class="oe_avatar" width="24" height="24" alt="" />
        </t>
    </div>
</t>

### 重复调用
<t t-call="follower_avatars" />
### 更优雅的方式实现 调用模板传递参数
# slice(0,arg_max)
<t t-name="follower_avatars">
    <div>
        <t t-foreach="record.message_partner_ids.raw_value.slice(0, arg_max)"
           t-as="rec">
            <img t-att-src="kanban_image('res.partner', 'image_small', rec)"
                 class="oe_avatar" width="24" height="24" alt="" />
        </t>
    </div>
</t>

### 子模板调用时定义arg_max变量
<t t-call="follower_avatars">
    <t t-set="arg_max" t-value="3" />
</t>
字典和列表动态属性
### 映射
# 定义:<p t-att="{'class': 'oe_bold', 'name': 'Hello'}" />
# 输出:<p class="oe_bold" name="Hello" />

### pair
# 定义:<p t-att="['class', 'oe_bold']" />
# 输出:<p class="oe_bold" />

四·看板视图的继承

# 与普通视图的继承一样
# XPath 查找<t t-name=”kanban-box”>元素内的<field name=”display_name”>
<record id="res_partner_kanban_inherit" model="ir.ui.view">
    <field name="name">Contact Kanban modification</field>
    <field name="model">res.partner</field>
    <field name="inherit_id" ref="base.res_partner_kanban_view" />
    <field name="arch" type="xml">
        <xpath expr="//t[@t-name='kanban-box']//field[@name='display_name']"
               position="before">
            <span>Name:</span>
        </xpath>
    </field>
</record>

五·自定义 CSS 和 JavaScript

# 自定义css和js文件

# 步骤 
	# 1. 在views目录下新建checkout_kanban_assets.xml数据文件加载样式
	# 2. 在static/src/css编写css  src/js编写js
	# 3. 将数据文件加载到__manifest__.py的data种
	
# library_checkout/views/checkout_kanban_assets.xml:
<odoo>
    <template id="assets_backend" inherit_id="web.assets_backend"
        name="Library Checkout Kanban Assets">
        <xpath expr="." position="inside">
            <link rel="stylesheet"
                href="/library_checkout/static/src/css/checkout_kanban.css" />
            <script type="text/javascript"
                src="/library_checkout/static/src/js/checkout_kanban.js">
            </script>
        </xpath>
    </template>
</odoo>
上一篇:【题解】Luogu P1195 口袋的天空


下一篇:APIO2020 粉刷墙壁