第 3 章:自定义看板视图

我们已经了解了 Web 框架提供的众多功能。下一步,我们将自定义一个看板视图。这是一个更复杂的项目,将展示框架的一些非平凡特性。目标是练习组合视图、协调用户界面的各个方面,并以可维护的方式完成它。

Bafien 提出了一个绝妙的想法:将看板视图和列表视图结合起来,这将是完美的解决方案!简而言之,他希望在 CRM 看板视图的左侧显示客户列表。当您点击左侧边栏中的某个客户时,右侧的看板视图会过滤,仅显示与该客户相关的线索。

目标

../../../_images/overview3.png

本章每个练习的解决方案托管在 官方 Odoo 教程仓库 中。

1. 创建一个新的看板视图

由于我们要自定义看板视图,让我们从扩展它开始,并在 CRM 的看板视图中使用我们的扩展。

  1. 创建一个新的空组件,扩展来自 @web/views/kanban/kanban_controllerKanbanController 组件。

  2. 创建一个新的视图对象,并从 @web/views/kanban/kanban_view 中的 kanbanView 分配所有键和值。通过放入新创建的控制器来覆盖 Controller 键。

  3. 在视图注册表中将其注册为 awesome_kanban

  4. 更新 awesome_kanban/views/views.xml 中的 CRM 看板架构以使用扩展视图。这可以通过在看板节点中指定 js_class 属性来完成。

2. 创建一个 CustomerList 组件

我们需要显示客户列表,因此我们可以直接创建该组件。

  1. 创建一个 CustomerList 组件,目前只显示一个带有文本的 div

  2. 它应该有一个 selectCustomer 属性。

  3. 创建一个新的模板,扩展(XPath)看板控制器模板 web.KanbanView,将 CustomerList 添加到看板渲染器旁边。暂时为其提供一个空函数作为 selectCustomer

    小技巧

    您可以在模板中使用此 XPath,在渲染器组件之前添加一个 div

    <xpath expr="//t[@t-component='props.Renderer']" position="before">
       ...
    </xpath>
    
  4. 子类化看板控制器,将 CustomerList 添加到其子组件中。

  5. 确保您能在看板视图中看到您的组件。

../../../_images/customer_list_component.png

参见

模板继承

3. 加载并显示数据

  1. 修改 CustomerList 组件,在 onWillStart 中获取所有客户的列表。

  2. 使用 t-foreach 在模板中显示列表。

  3. 每当选择一个客户时,调用 selectCustomer 函数属性。

../../../_images/customer_data.png

4. 更新主看板视图

  1. 在看板控制器中实现 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
    }])
    
  2. 通过点击多个客户,您可以看到旧的客户过滤器没有被替换。确保点击某个客户时,旧的过滤器会被新的过滤器替换。

    小技巧

    您可以使用此代码片段获取客户过滤器并切换它们。

    const customerFilters = this.env.searchModel.getSearchItems((searchItem) =>
          searchItem.isFromAwesomeKanban
    );
    
    for (const customerFilter of customerFilters) {
       if (customerFilter.isActive) {
             this.env.searchModel.toggleSearchItem(customerFilter.id);
       }
    }
    
  3. 修改模板,为 CustomerListselectCustomer 属性赋予实际功能。

注解

您可以使用 Symbol 来确保自定义的 isFromAwesomeKanban 键不会与其他代码可能添加到对象中的键发生冲突。

../../../_images/customer_filter.png

5. 仅显示有活跃订单的客户

res.partner 上有一个 opportunity_ids 字段。让我们允许用户筛选至少有一个商机的客户。

  1. CustomerList 组件中添加一个复选框输入框,并在其旁边添加标签“活跃客户”。

  2. 更改复选框的值应该会过滤客户列表。

../../../_images/active_customer.png

6. 在客户列表中添加一个搜索栏

在客户列表上方添加一个输入框,允许用户输入字符串并根据客户名称过滤显示的客户。

小技巧

您可以使用来自 @web/core/utils/searchfuzzyLookup 函数来执行过滤。

../../../_images/customer_search.png

7. 重构代码以使用 t-model

为了解决前两个练习,您可能在输入上使用了事件监听器。让我们看看如何以更声明式的方式实现,使用 t-model 指令。

  1. 确保您有一个响应式对象来表示过滤器是否处于活动状态(例如 this.state = useState({ displayActiveCustomers: false, searchString: ''}))。

  2. 修改代码以添加一个 getter displayedCustomers,返回当前活动的客户列表。

  3. 修改模板以使用 t-model

8. 对客户进行分页!

  1. CustomerList 中添加一个 分页器 ,并仅加载/渲染前 20 个客户。

  2. 每当分页器发生变化时,客户列表应相应更新。

这实际上相当困难,特别是在结合上一个练习中完成的过滤功能时。需要考虑许多边缘情况。

../../../_images/customer_pager.png