第3章:自定义看板视图¶
我们已经了解了 Web 框架提供的众多功能。接下来,我们将自定义一个看板视图。这是一个更复杂的项目,将展示框架的一些非平凡方面。目标是练习组合视图、协调 UI 的各个方面,并以可维护的方式进行。
Bafien 有了一个绝妙的想法:看板视图和列表视图的结合将完美满足你的需求!简而言之,他希望 CRM 看板视图的左侧显示客户列表。当你点击左侧边栏中的客户时,右侧的看板视图将过滤,仅显示与该客户相关的线索。
目标

本章每个练习的解决方案都托管在 官方 Odoo 教程仓库 上。
1. 创建一个新的看板视图¶
既然我们要自定义看板视图,让我们从扩展它开始,并在CRM的看板视图中使用我们的扩展。
创建一个新的空组件,该组件继承自
@web/views/kanban/kanban_controller
中的KanbanController
组件。创建一个新的视图对象,并从
@web/views/kanban/kanban_view
中的kanbanView
分配所有键和值。通过放置你新创建的控制器来覆盖 Controller 键。在
awesome_kanban
下将其注册到视图注册表中。更新
awesome_kanban/views/views.xml
中的 crm kanban arch 以使用扩展视图。这可以通过在 kanban 节点中指定js_class
属性来完成。
另请参阅
2. 创建一个 CustomerList 组件¶
我们需要展示客户列表,因此我们可以创建该组件。
创建一个
CustomerList
组件,目前只显示一个带有一些文本的div
。它应该有一个
selectCustomer
属性。创建一个新模板,通过扩展(XPath)看板控制器模板
web.KanbanView
,在看板渲染器旁边添加CustomerList
。暂时为其提供一个空函数selectCustomer
。小技巧
你可以在模板中使用此 xpath 在渲染器组件之前添加一个 div。
<xpath expr="//t[@t-component='props.Renderer']" position="before"> ... </xpath>
子类化看板控制器,在其子组件中添加
CustomerList
。确保您在看板视图中看到了您的组件。

另请参阅
3. 加载并显示数据¶
修改
CustomerList
组件,在onWillStart
中获取所有客户的列表。使用
t-foreach
在模板中显示列表。每当选择了一个客户,调用
selectCustomer
函数属性。

另请参阅
4. 更新主看板视图¶
在看板控制器中实现
selectCustomer
以添加正确的域。小技巧
由于与搜索视图的交互并非易事,这里提供一个创建过滤器的代码片段:
this.env.searchModel.createNewFilters([{ description: partner_name, domain: [["partner_id", "=", partner_id]], isFromAwesomeKanban: true, // this is a custom key to retrieve our filters later }])
通过点击多个客户,您可以看到旧的客户筛选条件并未被替换。请确保点击某个客户时,旧的筛选条件会被新的所替换。
小技巧
您可以使用此代码片段来获取客户筛选器并进行切换。
const customerFilters = this.env.searchModel.getSearchItems((searchItem) => searchItem.isFromAwesomeKanban ); for (const customerFilter of customerFilters) { if (customerFilter.isActive) { this.env.searchModel.toggleSearchItem(customerFilter.id); } }
修改模板,将真实的功能赋给
CustomerList
的selectCustomer
属性。
注解
你可以使用 Symbol 来确保自定义的 isFromAwesomeKanban
键不会与任何其他代码可能添加到对象中的键发生冲突。

5. 仅显示有有效订单的客户¶
在 res.partner
上有一个 opportunity_ids
字段。让我们允许用户筛选出至少有一个商机的客户结果。
在
CustomerList
组件中添加一个类型为复选框的输入框,并在旁边加上标签“活跃客户”。更改复选框的值应过滤客户列表。

6. 在客户列表中添加搜索栏¶
在客户列表上方添加一个输入框,允许用户输入字符串并根据客户姓名过滤显示的客户。
小技巧
你可以使用 @web/core/utils/search
中的 fuzzyLookup
函数来执行过滤。

另请参阅
需要翻译的内容是:
7. 重构代码以使用 t-model
¶
为了解决前两个练习,你可能在输入框上使用了一个事件监听器。让我们看看如何以更加声明性的方式来完成,使用 t-model 指令。
确保你有一个反应式对象来表示过滤器是否激活(类似于
this.state = useState({ displayActiveCustomers: false, searchString: ''})
)。修改代码以添加一个名为
displayedCustomers
的 getter,该 getter 返回当前活动的客户列表。修改模板以使用
t-model
。
8. 分页显示客户!¶
在
CustomerList
中添加一个 pager,并且只加载/渲染前20个客户。每当分页器改变时,客户列表应相应更新。
这实际上非常困难,特别是与前面练习中的过滤相结合。需要考虑许多边缘情况。
