元素动态设置一个类,这样卡片可根据 color 字段值来显示颜色。为此使用了t-attf- QWeb指令。t-attf-指令使用字符串替换动态生成标签属性。这让像 URL 地址或 CSS 类名这类较大字符串中的部分内容可动态生成。该指令查找表达式代码块进行运行并替换结果。它们通过{{和}} 或#{和}来进行分隔。代码块的内容可以是任意JavaScript表达式并使用QWeb表达式中的任意可用变量,如record和widget。本例中我们还使用了专门提供的kanban_color() JS 函数,用于映射索引值到类颜色名。
作为一个更复杂的示例,我们使用这个指令来动态生成用户的颜色,红色字体表示优先级很高。下面替换看板卡片中的相应代码:
<li t-attf-class="oe_kanban_text_{{
record.priority.raw_value lt '2'
? 'black' : 'red'}}">
<field name="user_id" />
</li>
这将会根据借阅优先级的值生成class=“oe_kanban_text_red”或class=“oe_kanban_text_black”。请注意看板视图中是有oe_kanban_text_red这个 CSS 类的,但oe_kanban_text_black仅用于演示,实际并不存在。
ℹ️注意JavaScript表达式中使用的lt符号,是<的转义表达式,并不能在XML中使用。

表达式动态属性 - t-att
t-att- QWeb指令通过运行表达式动态生成属性值。我们的看板卡片中使用它来为
标签动态生成属性,title 属性使用以下表达式动态渲染:
t-att-title="record.member_id.value"
.value字段返回在屏幕上显示的值。对于many-to-one字段,这通常是相关记录的 name 值。对于用户则是用户名。运行之后在鼠标悬停于图像上时会显示相应的用户名。
在表达式运行的结果值为假时,就不会渲染该属性。这对于特殊的 HTML 属性非常重要,比如 input 字段中的 checked,即便在没有属性值时也会有显示效果。

循环 - t-foreach
通过循环遍历来重复同一 HTML 代码块。我们可使用它来添加记录 follower 的头像。让我们先来仅渲染记录的partner ID:
<t t-foreach="record.message_partner_ids.raw_value" t-as="rec">
<t t-esc="rec" />;
</t>
t-foreach指令接收一个JavaScript表达式,运行来遍历集合。在大多数情况下,这会是 一个to-many关联字段的名称。与t-as指令一同使用来设置用于引用遍历各项的名称。下面使用的t-esc指令运行所提供的表达式,本处仅为 rec 变量名,将其渲染为已转译的安全 HTML。
在上例中,我们遍历了存储在message_partner_ids 字段中的 follower。因为在看板卡片上的空间有限,我们使用JS 的slice()函数来限定所显示的follower数量,如下所示:
t-foreach="record.message_partner_ids.raw_value.slice(0, 3)"
rec变量存储每个遍历值,本例中为partner ID。这样我们可以将循环改写为:
<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>
比如可将其添加在右侧 footer 的用户头像旁。还包含一些帮助变量,它们的名称以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 (rec存储键名)
例如可通过如下代码去除ID 列表最后逗号:
<t t-foreach="record.message_parter_ids.raw_value.slice(0, 3)"
t-as="rec">
<t t-esc="rec" />
<t t-if="!rec_last">;</t>
</t>

条件判断 - t-if
我们的看板视图在卡片选项菜单中使用了t-if指令来根据不同条件显示不同选项。t-if指令在客户端渲染看板视图时需传入在 JS 中运行的表达式。标签和其内容仅在条件运行值为true 时才会渲染。作为示例,仅在借出有值时显示图书借出数量,在request_date字段后加入如下代码:
<t t-if="record.num_books.raw_value gt 0">
<li><field name="num_books" /> books</li>
</t>
我们使用了元素,这样在条件为 false 时,元素不会有任何输出。在为 true 时,仅会渲染其所包含的
元素来进行输出。注意条件表达式中使用gt符号来替代>以表示大于运算符。可通过t-elif和t-else来支持else if和else条件语句,使用示例如下: <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>
Javascript表达式中,AND和OR的运算符分别为&&和 ||。但在 XML 中不支持&符号,我们可以使用 and 和 or 运算符来规避这一问题。

渲染值 - t-esc和t-raw
我们使用了元素来渲染值,但也可以无需标签直接显示字段值。t-esc指令运行表达式并将其渲染为转义后的 HTML 值,如下所示:
<t t-esc="record.message_partner_ids.raw_value" />
有些情况下,如果确定源数据是安全的,可以无需转义使用t-raw 来渲染原始值,如下例所示:
<t t-raw="record.message_partner_ids.raw_value" />
**小贴士:**出于安全考虑,应尽量避免使用t-raw。它应严格用于输出特别准备不包含用户数据的HTML 数据,或者是已明确对 HTML 特殊字符转义的用户数据。
为变量设置值 - t-set
对于更复杂的逻辑,我们可以将表达式结果存储在变量中,在模板中随后使用。这通过t-set指令来实现,它设置变量名,紧接着使用t-value指令来添加表达式计算分配的值。作为示例,以下代码将优先级较高的和前面一节一样渲染为红色,但使用red_or_black 变量来作为 CSS 类使用的变量,如下所示:
<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>
变量中也可分配 HTML内容,示例如下:
<t t-set="calendar_sign">
<i class="fa fa-calendar" />
</t>
<t t-raw="calendar_sign" />

调用和复用其它模板 - t-call
QWeb模板可作为可复用的 HTML 片段插入到其它模板中。我们无需重复相同的 HTML 代码块,可以设计构成部分来组成更为复杂的用户界面视图,可复用的模板在标签中定义,通过顶级元素中 kanban-box 以外的 t-name值进行标识。这些模板可通过t-call来进行包含,在当前看板视图、相同模块的其它地方以及其它插件模块中均可。
follower头像列表可以通过可复用代码段来进行分离,下面通过子模板重写代码。首先应在 XML 文件中添加另一个模板,在元素内,节点之后,添加如下代码:
<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>
在kanban-box主模板调用它就简单明了了,将原来包含 for each 指令的