Joomla 资料库 MVC 类
Joomla 提供了多个控制器、视图和模型资料库类,本部分概述了这些类,并说明了您的组件何时应使用各类型。但是,它不会尝试对各个类的功能提供全面的描述。可在 libraries/src/MVC 中找到这些类。
基本 MVC 类
实际上,您最可能使用的最低级别的类是
- libraries/src/MVC/Controller/BaseController.php 中的 BaseController
- libraries/src/MVC/View/HtmlView.php 中的 HtmlView(用于显示网页)
- libraries/src/MVC/Model/BaseDatabaseModel.php 中的 BaseDatabaseModel
(如果您的组件用 JSON 编码的对象响应了 Ajax 调用,则您将使用 libraries/src/MVC/View/JsonView.php。)
通常,如果组件在站点页面上显示单个项目,那么使用这些基础类是一个不错的选择。
BaseController
BaseController 中的功能包括
- 上文描述的
execute()
方法,它将运行适当的 Controller 函数,该函数基于 task 参数的<method>
部分(传递给它)。 - 用于确定要使用的适当 View 和 Model 类(基于 HTTP 请求中 view 参数的设置)的函数,以及获取 MVCFactory 类创建它们
- 默认
display()
方法,它获取 View 和 Model 类实例(包括向 View 实例提供与 Model 实例的链接),然后调用 View 类的display()
方法。
HtmlView
HtmlView 中的功能包括
- 默认
display()
方法,它将运行 tmpl 文件 - 用于查找 tmpl 文件的代码,考虑到可能放入模板文件夹结构中布局覆盖
- 用于设置模型实例并随后检索它的代码
BaseDatabaseModel
BaseDatabaseModel 中的功能包括
- 用于获取 Table 类实例(通过 MVCFactory 类)的代码
- 创建模型“状态”的基本代码。此功能非常有用,前提是组件和/或网页上显示的多个模块都使用相同的基本数据。在这种情况下,它们可能会共享同一个 Model 实例,而模型“状态”就像一个容器,用于在组件和模块间共享项目值。
更高级别的 Controller 类
有两个高级别控制器类,每个类都继承自 BaseController。
AdminController
AdminController 包含处理针对多个项目可执行的操作类型的方法,例如
- 删除
- 签到
- 更改发布状态
- 更改记录的相对顺序
该代码通常调用相关的 Model 方法来执行操作、根据 Model 操作的成功来设置消息,并设置重定向回同一页面的方法。因此,它在上文图表中 发送/请求/获取模式 部分所示的动作 2 中非常有用。
AdminController 名称暗示此控制器仅可在后端管理员功能中使用,但并非如此。在站点前端中使用它也很合适。
但请注意,它不支持通过 Content/Articles 等页面上的“批处理”按钮启用操作;这些 POST 请求由 FormController 处理。
FormController
FormController 包含与编辑单项关联的方法
- 处理编辑项的请求——包括检查用户是否允许编辑该项以及该项是否未检出,如果这些检查通过,则检出该项(如果该组件启用了检出)并发出重定向以显示编辑表单
- 处理添加新项的请求——包括检查用户是否允许创建该项并导致重定向以显示一个空白编辑表单
- 处理正在从新项中编辑或创建的项的“保存”——此代码检查用户是否允许执行操作,并调用相应的模型方法保存新项/已编辑项。
- 处理编辑的“取消”,将用户重定向回相应的页面(并在需要时检入记录)。
- 处理通过“批处理”按钮发起的操作
因此,FormController 非常适合上面图示中 Post/Request/Get 模式 部分中显示的操作 3 和 5。
更高级别的视图类
除了用于生成 Feed 的 CategoryFeedView 之外,还有两种更高级别的视图类常用
- CategoryView – 用于显示类别及其子类别
- CategoriesView – 用于显示类别层次结构中特定层级的所有类别以及与每个类别关联的项目数量
ListView 和 FormView 这两个类似乎针对显示记录列表(如 com_content
管理员 View\Articles\HtmlView)和编辑记录的表单(如 com_content
管理员 View\Article\HtmlView)的功能。但是,在撰写本文时(最近出现了 Joomla 5 alpha),它们不会被任何 Joomla 组件使用,所以我不建议使用它们,至少现在还不行。
更高级别的模型类
该图显示了 Joomla 库 MVC 模型的继承树。
ItemModel 和 BaseDatabaseModel 几乎相同。它只多了一个 getStoreId()
方法,在以下情况下它将非常有用:您有一个组件和/或多个模块共享同一个模型,您想区分与每个模块相关的各个数据集。
除了 getStoreId()
以外,ListModel 还具有获取一组记录以在网页上显示的能力,包括对分页的支持。请注意,分页能力在前段和后段之间可能仍然存在一些差异。ListModel 适用于支持 Post/Request/Get 模式部分中图表中的操作 1。
FormModel 包括对 Joomla 表单的支持,用于设置表单以便可以显示,还用于验证 POST 中发送的表单数据。此外,它还具有实现数据库记录签入和签出的方法。因此它适用于处理图表中的操作 3 和 4。
AdminModel 扩展了 FormModel,因此它具有处理表单的所有能力,但此外还具有处理数据库更新的方法——包括添加、更新和删除记录的能力——以及对批量处理操作的支持。因此它适用于处理图表中的操作 2 和 5。与 AdminController 一样,此模型不仅适用于管理员功能,还可以在前段使用。
然而,尽管 FormModel 和 AdminModel 支持编辑记录时流程中的不同情况,但实际上通常对流程中的所有不同步骤使用同一个模型。所有 Joomla 核心组件在这些步骤中使用同一个模型,因此它们全都扩展 AdminModel 而非 FormModel。
如果您对“编辑项”流程使用同一个模型,那么需要注意的一点是,您的模型代码正在执行 2 个用途
- 准备数据以在网页上显示
- 准备一个表单,既可以显示在网页上,也可以用来验证 POST 数据
当因为要处理 POST 而使用模型时(即,图表中的情况 3 和 5),那么为准备网页数据所做出的任何努力都是浪费的。(事实上,在 FormController getModel()
方法调用中,参数 $config
默认设为 array('ignore_request' => true)
,结果是模型的 populateState
方法没有运行,以节省这些无效的努力。)
摘要
正如我们所看到的,Joomla 在更高级别的控制器和模型类中具有丰富的功能,这可以极大地简化您的代码(所有这些功能都可以在前段和后段使用)。
选择要扩展哪些控制器和模型类在后端更为容易,因为您只需遵循 Joomla 核心组件的模式即可。
对于前端,这里有一个选择最适合要扩展的控制器和模型类的粗略指南;在每种情况下,您都使用标准的HtmlView作为要扩展的基本视图类。
简单显示
仅显示记录或一组记录,而不提供更改任何内容的能力
- 控制器继承BaseController
- 模型继承BaseDatabaseModel或(尤其是在组件与模块之间共享模型时)如果是单条记录,则为ItemModel,如果是多条记录,则为ListModel。
显示记录,以及对所选记录的操作
显示包含多条记录的表单(但该表单未在XML文件中定义),包括提供选择多条记录并对它们应用某种操作(例如,删除、发布)的能力
- 控制器继承BaseController
- 模型继承ListModel - 除非您使用相同的模型显示表单并处理更新,在这种情况下,请使用AdminModel
处理来自上述的HTTP POST
- 控制器继承AdminController
- 模型继承AdminModel
编辑记录
显示包含单条记录的表单,其中表单在XML文件中定义,并允许用户对其进行编辑,或显示空白记录,并允许用户创建记录
- 控制器继承BaseController
- 模型扩展FormModel - 除非您将相同的模型用于显示表单和处理更新(通常情况下是此情况),在这种情况下,请使用AdminModel
处理来自上述的HTTP POST
- 控制器继承FormController
- 模型继承AdminModel