任务树

框架的所有对象被组织为一个对象树。这些对象被称为实体项。

树中的所有实体项都有一个共同的祖先类 AbstractItem ( 客户端参考 / 服务端参考 ),并具有以下共同属性:

  • ID - 标识实体项的 ID ,在框架内唯一

  • 所有者(owner) - 实体项的直接父级和所有者

  • 任务(task) - 任务树的根节点

  • 子项(items) - 子实体项列表

  • 类型(item_type) - 该实体项的类型

  • 名称(item_name) - 该实体项的名称,在编程代码中用于访问该实体项

  • 标题(item_caption) - 向用户显示的描述该实体项的标题

树的根节点是 “任务(task)” 实体项。

“任务(task)” 实体项包含子实体项组(group items)。实体项组共有三种类型,其 item_type 属性对应以下取值(取值由组决定,无法手动修改):

  • “业务台账(journals)” - 这个组里包含 item_type 为 “item” 的实体项,这些实体项可以有与之关联的数据库表。

  • “主表目录(catalogs)” - 这个组里也包含可以有与之关联的数据库表的实体项,但它们可用于为其他实体项创建明细表(参见 明细表 )。

  • “报表(reports)” - 这个组里包含报表 - item_type 为 “report” 的实体项,用于创建报表。

组的数量没有限制。建议为组命名时使用具备业务逻辑含义的名称,因为该名称会用于下拉菜单。

有与之关联的数据库表的实体项可以拥有明细表,这类明细表用于存储属于主表记录的子记录。

例如, 演示项目 的任务树为

/demo/
    journals/
        invoices/
            invoice_table
        invoices_on_client/
            invoice_table
    catalogs/
       customers
       tracks/
            invoice_table
       albums
       artists
       genres
       mail
    details/
        invoice_table
    reports/
        invoice
        purchases_report
        customer_list
    analytics
        dashboard
    system/
        history

任务树的根节点是一个 实体项名称(item_name)demo 的任务。它包含 五个组: catalogsjournalsdetailsreportsanalyticssystemcatalogsjournals 组的 item_type 为 “items” 。它们所对应的实体项 是对应数据库表的包装器。有一个明细表实体项,其 实体项名称(item_name)invoice_table , 它也有自己的数据库表,而 reports 组中有三个报表。

发票(invoices) 业务台账拥有 invoice_table 明细表,用于保存销售给客户的曲目列表。 因此,有三个同名的 “invoice_table” 实体项:“明细” 组中的明细表、 Journal/Invoices 下的明细表以及 Catalogs/Tracks 下的明细表。

每个实体项都是其所有者的属性,所有实体项、数据表和报表也都是 “任务” 的属性(它们都有唯一的 实体项名称(item_name) )。

在客户端,“任务” 是一个全局对象。要在代码中的任何位置访问它,只需输入 task

在服务器端,任务不是全局的。Jam.py 是一个事件驱动的环境。 每个事件都有一个触发该事件的实体项(或字段)参数。 在实体项的服务器模块中定义的函数可以通过 server 方法从客户端模块中执行,这些函数的第一个参数也是相应的实体项。

了解了一个实体项后,我们就可以访问任务树中的任何其他实体项。 例如,要访问 客户(customers) 主表项,我们可以这样写:

def on_apply(item, delta, params):
    customers = item.task.catalogs.customers.copy()

或者直接写:

def on_apply(item, delta, params):
    customers = item.task.customers.copy()

项目的层次结构是该框架 DRY (don't repeat yourself,不要重复自己)原则的核心基础之一。

例如,实体项(item)的一些方法在执行时,会按顺序为任务(task)、实体组(group)和实体项(item)生成事件。

借助这种机制,我们可在任务的事件处理器中为所有实体项定义基础行为;该基础行为可在实体组的事件处理器中进行扩展;最终,若有需要,还可在实体项自身的事件处理器中对其进行定制化调整。 更多详细信息,请参阅 表单窗体事件

视频

任务树(Task tree) 视频教程使用 演示项目 演示了如何使用任务树。