此 Backend\Behaviors\RelationController 类是一个控制器行为用于轻松管理页面上的复杂 模型 关系。
关系行为取决于如下指定的关系类型. 为了使用关系行为,您应该将 Backend\Behaviors\RelationController 定义添加到控制器类的 $implement 字段中. 此外,$relationConfig 类属性应该被定义,并且其值应该引用用于配置行为属性的 YAML 文件.
namespace Acme\Projects\Controllers;
class Projects extends Controller
{
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\RelationController::class
];
public $formConfig = 'config_form.yaml';
public $relationConfig = 'config_relation.yaml';
}通常,关联控制器与表单控制器结合使用。
:::
在 $relationConfig 属性中引用的配置文件是 YAML 格式的。 该文件应放置在 控制器的视图目录。 所需的配置取决于目标模型与相关模型之间的关系类型。
关系配置文件中的第一级字段定义了目标模型中的关系名称。例如。
class Invoice extends Model
{
public $hasMany = [
'items' => \Acme\Pay\Models\InvoiceItem::class,
];
}带有名为 items 关系的 Invoice 模型应该使用相同的关系名称定义第一级字段。
# config_relation.yaml
items:
label: Invoice Line Item
view:
list: $/acme/pay/models/invoiceitem/columns.yaml
toolbarButtons: create|delete
recordsPerPage: 10
manage:
form: $/acme/pay/models/invoiceitem/fields.yaml以下属性然后用于每个关系名称定义。
| Property | Description |
|---|---|
| label | a label for the relation, in the singular tense, required. |
| view | configuration specific to the view container, see below. |
| manage | configuration specific to the management popup, see below. |
| pivot | a reference to form field definition file, used for relations with pivot table data. |
| emptyMessage | a message to display when the relationship is empty, optional. |
| readOnly | disables the ability to add, update, delete or create relations. Default: false |
| deferredBinding | defers all binding actions using a session key when it is available. default: false |
| popupSize | change the size of the management popups used, either: giant, huge, large, small, tiny or adaptive. Default: huge |
| valueFrom | defines a custom model attribute to use for the source value. Default comes from the definition name. |
这些配置值可以为 view 或 manage 属性指定,在适用于列表、表单或两者兼有的渲染类型时。
| Property | Type | Description |
|---|---|---|
| form | Form | a reference to form field definition file, see backend form fields. |
| list | List | a reference to list column definition file, see backend list columns. |
| showFlash | Both | enables the display of flash messages after a successful action. Default: true |
| showSearch | List | display an input for searching the records. Default: false |
| showSorting | List | displays the sorting link on each column. Default: true |
| showSetup | List | displays a setup button to configure the list columns and records per page. Default: false |
| defaultSort | List | sets a default sorting column and direction when user preference is not defined. Supports a string or an array with keys column and direction. The direction can be asc for ascending (default) or desc for descending order. |
| recordsPerPage | List | maximum rows to display for each page. |
| noRecordsMessage | List | a message to display when no records are found, can refer to a localization string. |
| conditions | List | specifies a raw where query statement to apply to the list model query. |
| scope | List | specifies a model query scope method defined in the related form model to apply to the list query always. The model that this relationship will be attached to (i.e. the parent model) is passed to this scope method as the second parameter ($query is the first). |
| searchMode | List | defines the search strategy to either contain all words, any word or exact phrase. Supported options: all, any, exact. Default: all. |
| searchScope | List | specifies a model query scope method defined in the related form model to apply to the search query, the first argument will contain the search term. |
| filter | List | a reference to a filter scopes definition file, see backend list filters. |
| customPageName | List | specify a custom variable name to use in the page URL for paginated records. Set to false to disable storing the page number in the URL. |
这些配置值只能针对 view 属性指定。
| Property | Type | Description | |
|---|---|---|---|
| showCheckboxes | List | displays checkboxes next to each record. | |
| recordUrl | List | link each list record to another page. Eg: users/update/:id. The :id part is replaced with the record identifier. | |
| customViewPath | List | specify a custom view path to override partials used by the list. | |
| recordOnClick | List | custom JavaScript code to execute when clicking on a record. | |
| toolbarPartial | Both | a reference to a controller partial file with the toolbar buttons. Eg: _relation_toolbar.php. This property overrides the toolbarButtons property. | |
| toolbarButtons | Both | the set of buttons to display. This can be formatted as an array or a pipe separated string, or set to false to show no buttons. Available options are: create, update, delete, add, remove, link, & unlink. Example: `add | remove`. |
| structure | List | options to enable sorting records for the list. |
这些配置值只能针对 manage 属性指定。
| Property | Type | Description |
|---|---|---|
| title | Both | a popup title, can refer to a localization string. |
| context | Form | context of the form being displayed. Can be a string or an array with keys: create, update. |
指定 customMessages 属性以覆盖关系控制器使用的默认消息。这些值可以是纯文本,也可以引用一个 本地化字符串。
customMessages:
buttonCreate: Make Thing
buttonDelete: Destroy Thing您还可以在显示的关联字段的上下文中修改消息。以下内容将仅覆盖 items 关联的 createButton 消息。
items:
customMessages:
buttonCreate: New Item!以下消息可重写为自定义消息。
::: details 查看可用消息列表
| Message | Default Message |
|---|---|
| buttonCreate | Create :name |
| buttonCreateForm | Create |
| buttonCancelForm | Cancel |
| buttonCloseForm | Close |
| buttonUpdate | Update :name |
| buttonUpdateForm | Update |
| buttonAdd | Add :name |
| buttonAddMany | Add Selected |
| buttonAddForm | Add |
| buttonLink | Link :name |
| buttonDelete | Delete |
| buttonDeleteMany | Delete Selected |
| buttonRemove | Remove |
| buttonRemoveMany | Remove Selected |
| buttonUnlink | Unlink |
| buttonUnlinkMany | Unlink Selected |
| confirmDelete | Are you sure? |
| confirmUnlink | Are you sure? |
| titlePreviewForm | Preview :name |
| titleCreateForm | Create :name |
| titleUpdateForm | Update :name |
| titleLinkForm | Link a New :name |
| titleAddForm | Add a New :name |
| titlePivotForm | Related :name Data |
| flashCreate | :name Created |
| flashUpdate | :name Updated |
| flashDelete | :name Deleted |
| flashAdd | :name Added |
| flashLink | :name Linked |
| flashRemove | :name Removed |
| flashUnlink | :name Unlinked |
| ::: |
关系控制器支持嵌套关系,换句话说,通过关系管理关系。嵌套关系使用标准的字段嵌套语法。例如,countries[cities] 关系定义使 cities 关系可以通过 countries 关系进行管理。
countries:
label: Country
form: $/acme/location/models/country/fields.yaml
list: $/acme/location/models/country/columns.yaml
countries[cities]:
label: City
form: $/acme/location/models/city/fields.yaml
list: $/acme/location/models/city/columns.yaml嵌套关系定义旨在与 关系表单小部件 无缝协作,并将
useController属性设置为true。
关系管理器如何显示取决于目标模型中的关系定义。关系类型还将决定配置要求,这些要求以 粗体 显示。以下关系类型可用:
view.list)。manage.form).manage.list)。manage.form)。例如,如果一个博客文章包含许多评论,目标模型被设置为该博客文章,并显示评论列表,使用list定义中的列。点击评论会打开一个弹出表单,其中包含form中定义的字段,以更新评论。评论也可以以同样的方式创建。下面是关系行为配置文件的示例。
# config_relation.yaml
comments:
label: Comment
manage:
form: $/acme/blog/models/comment/fields.yaml
list: $/acme/blog/models/comment/columns.yaml
view:
list: $/acme/blog/models/comment/columns.yaml
toolbarButtons: create|deleteview.list)。manage.list)。manage.form)。例如,如果一个 用户 属于多个 角色,目标模型被设置为用户并显示一个角色列表,使用来自 list 定义的列。现有角色可以从用户中添加和移除。下面是关系行为配置文件的一个示例。
# config_relation.yaml
roles:
label: Role
view:
list: $/acme/user/models/role/columns.yaml
toolbarButtons: add|remove
manage:
list: $/acme/user/models/role/columns.yaml
form: $/acme/user/models/role/fields.yamlview.list)。pivot.form).manage.list),然后是一个数据录入表单 (pivot.form)。继续多对多关系中的示例,如果一个角色也包含一个有效期,点击一个角色将会打开一个弹出表单,其中包含在pivot中定义的字段,以更新有效期。下面是关系行为配置文件的示例。
# config_relation.yaml
roles:
label: Role
view:
list: $/acme/user/models/role/columns.yaml
manage:
list: $/acme/user/models/role/columns.yaml
pivot:
form: $/acme/user/models/role/fields.yaml透视数据在通过 pivot 关系定义表单字段和列表列时可用,请参见以下示例。
# config_relation.yaml
teams:
label: Team
view:
list:
columns:
name:
label: Name
pivot[team_color]:
label: Team color
manage:
list:
columns:
name:
label: Name
pivot:
form:
fields:
pivot[team_color]:
label: Team colorview.form).manage.form)。manage.form).manage.list)。例如,如果一个 电话 属于一个 人 关系管理器将显示一个表单,其字段定义于form。点击“链接”按钮将显示一个人员列表,以便与该电话关联。点击“取消链接”按钮将使该电话与该人解除关联。
# config_relation.yaml
person:
label: Person
view:
form: $/acme/user/models/person/fields.yaml
toolbarButtons: link|unlink
manage:
form: $/acme/user/models/person/fields.yaml
list: $/acme/user/models/person/columns.yamlview.form)。manage.form)。manage.form)。manage.list)。例如,如果一个人员有一个电话关系管理器将显示一个表单,其中包含在 form 中定义的用于该电话的字段。当点击“更新”按钮时,会弹出一个窗口,其中字段现在可编辑。如果该人员已有一个电话这些字段会被更新,否则会为他们创建一个新的电话。
# config_relation.yaml
phone:
label: Phone
view:
form: $/acme/user/models/phone/fields.yaml
toolbarButtons: update|delete
manage:
form: $/acme/user/models/phone/fields.yaml
list: $/acme/user/models/phone/columns.yaml在任何页面上管理关系之前,必须首先在控制器中通过调用 initRelation 方法来初始化目标模型。
$post = Post::where('id', 7)->first();
$this->initRelation($post);表单控制器 将在其创建、更新和预览操作中自动初始化模型。
然后,可以通过调用 relationRender 方法来显示指定关系定义的关系管理器。例如,如果您想在 预览 页面上显示关系管理器,preview.htm 视图内容可能如下所示。
<?= $this->formRenderPreview() ?>
<?= $this->relationRender('comments') ?>你可以指示关系管理器以只读模式渲染通过将该属性作为第二个参数传递。
<?= $this->relationRender('comments', ['readOnly' => true]) ?>有时您可能希望修改默认的关联行为,有几种方法可以实现这一点。
提供了一个操作关系配置的机会。以下示例可用于根据模型的属性注入不同的 columns.yaml 文件。
public function relationExtendConfig($config, $field, $model)
{
// Make sure the model and field matches those you want to manipulate
if (!$model instanceof MyModel || $field !== 'myField') {
return;
}
// Show a different list for business customers
if ($model->mode == 'b2b') {
$config->view['list'] = '$/author/plugin_name/models/mymodel/b2b_columns.yaml';
}
}提供了一个操纵视图小部件的机会。例如您可能希望根据模型的属性来切换 showCheckboxes。
public function relationExtendViewWidget($widget, $field, $model)
{
// Make sure the model and field matches those you want to manipulate
if (!$model instanceof MyModel || $field !== 'myField') {
return;
}
if ($model->constant) {
$widget->showCheckboxes = false;
}
}由于小部件在此运行时周期点尚未完成初始化,您无法调用 $widget->removeColumn(). 该 addColumns() 方法,如 列表控制器文档 中所述,将按预期工作,但要删除列,我们需要侦听 'list.extendColumns' 事件,在 relationExtendViewWidget() 方法内. 以下示例展示了如何删除列.
public function relationExtendViewWidget($widget, $field, $model)
{
// Make sure the model and field matches those you want to manipulate
if (!$model instanceof MyModel || $field !== 'myField') {
return;
}
// This will work
$widget->bindEvent('list.extendColumns', function () use ($widget) {
$widget->removeColumn('my_column');
});
}提供了操纵你的关联的管理微件的机会。
public function relationExtendManageWidget($widget, $field, $model)
{
// Make sure the field is the expected one
if ($field !== 'myField') {
return;
}
// Manipulate widget as needed
}提供了操纵您的关联的枢轴部件的机会。
public function relationExtendPivotWidget($widget, $field, $model)
{
// Make sure the field is the expected one
if ($field !== 'myField') {
return;
}
// Manipulate widget as needed
}有两个过滤小部件,可以使用以下方法进行扩展,一个用于 RelationController 的视图模式,一个用于 RelationController 的管理模式。
public function relationExtendViewFilterWidget($widget, $field, $model)
{
// Extends the view filter widget
}
public function relationExtendManageFilterWidget($widget, $field, $model)
{
// Extends the manage filter widget
}关于如何在筛选器控件中以编程方式添加或移除作用域的示例,可以在 列表控制器文档 的 扩展筛选器作用域 部分中找到。
当管理组件进行更改时,视图组件通常会刷新,您可以使用此方法在此过程发生时注入附加容器。返回一个包含要发送到浏览器的额外值的数组,例如:
public function relationExtendRefreshResults($field)
{
// Make sure the field is the expected one
if ($field !== 'myField') {
return;
}
return ['#myCounter' => 'Total records: 6'];
}