第 3 章:自定义看板视图

我们已经了解了网页框架提供的各种功能。下一步,我们将自定义一个看板视图。这是一个更为复杂的项目,将展示框架的一些非显而易见的方面。目标是练习组合视图、协调用户界面的各个方面,并以一种可维护的方式进行操作。

巴芬想到了一个绝妙的主意:将看板视图和列表视图结合,会完全满足你的需求!简而言之,他希望在 CRM 看板视图的左侧显示一个客户列表。当你点击左侧侧边栏中的某个客户时,右侧的看板视图会过滤,仅显示与该客户相关的潜在客户。

目标

../../../_images/overview1.png

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

1. 创建新的看板视图

既然我们正在自定义看板视图,那么让我们首先对其进行扩展,并在CRM的看板视图中使用我们的扩展。

  1. 创建一个新空组件,该组件继承自 @web/views/kanban/kanban_controller 中的 KanbanController 组件。

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

  3. 将其注册到视图注册表中,使用 awesome_kanban

  4. awesome_kanban/views/views.xml 文件中更新 CRM 看板的 arch,以使用扩展视图。可以通过在看板节点中指定 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 以添加适当的 domain。

    小技巧

    由于与搜索视图交互并不简单,这里提供一个代码片段来创建筛选器:

    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/search 文件中的 fuzzyLookup 函数来执行筛选。

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

另请参见

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

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

  1. 确保你有一个响应式对象,用于表示筛选器是否激活(例如:this.state = useState({ displayActiveCustomers: false, searchString: ''}))。

  2. 将代码修改为添加一个获取器 displayedCustomers,该获取器返回当前激活的客户列表。

  3. 将模板修改为使用 t-model

8. 对客户进行分页!

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

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

这实际上相当困难,尤其是在与前一练习中进行的筛选相结合时。需要考虑许多边界情况。

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