后端关系

Introduction

关系行为 是控制器behavior 用于轻松管理复杂的model 页面上的关系。它不能与列出关系列 或者形成关系字段 只提供简单的管理。

关系行为取决于关系定义.为了使用关系行为,你应该添加\Backend\Behaviors\RelationController::class 的定义$implement 控制器类的属性。

namespace Acme\Projects\Controllers;

class Projects extends Controller
{
    /**
     * @var array List of behaviors implemented by this controller
     */
    public $implement = [
        \Backend\Behaviors\FormController::class,
        \Backend\Behaviors\RelationController::class,
    ];
}

NOTE: 关系行为经常与形式行为.

配置关系行为

关系行为将从一个 YAML 格式加载其配置config_relation.yaml 文件位于控制器的查看目录 (plugins/myauthor/myplugin/controllers/mycontroller/config_relation.yaml) 默认情况下。

这可以通过覆盖$relationConfig 控制器上的属性以引用不同的文件名或完整的配置数组:

public $relationConfig = 'my_custom_relation_config.yaml';

所需的配置取决于关系类型 目标模型和相关模型之间。

关系配置文件中的第一级字段定义目标模型中的关系名称。例如:

class Invoice {
    public $hasMany = [
        'items' => ['Acme\Pay\Models\InvoiceItem'],
    ];
}

一个Invoice 具有称为关系的模型items 应该使用相同的关系名称定义第一级字段:

# ===================================
#  Relation Behavior Config
# ===================================

items:
    label: Invoice Line Item
    view:
        list: $/acme/pay/models/invoiceitem/columns.yaml
        toolbarButtons: create|delete
    manage:
        form: $/acme/pay/models/invoiceitem/fields.yaml
        recordsPerPage: 10

您还可以自定义工具栏按钮的标签:

items:
    label: Invoice Line Item
    view:
        list: $/acme/pay/models/invoiceitem/columns.yaml
        toolbarButtons:
            create: Add a line item
            delete: Remove line item
    manage:
        form: $/acme/pay/models/invoiceitem/fields.yaml
        recordsPerPage: 10

然后将以下选项用于每个关系名称定义:

Option Description
label 需要单数时态关系的标签。
view 特定于视图容器的配置,请参见下文。
manage 特定于管理弹出窗口的配置,请参见下文。
pivot 对表单字段定义文件的引用,用于与数据透视表数据的关系.
emptyMessage 当关系为空时显示的消息,可选。
readOnly 禁用添加、更新、删除或创建关系的能力。默认:false
deferredBinding 使用会话密钥推迟所有绑定操作 可用时。默认:false

这些配置值可以指定为view 或者manage 选项,适用于列表、表单或两者的呈现类型。

Option Type Description
form Form 对表单字段定义文件的引用,请参阅后端表单域.
list List 对列表列定义文件的引用,请参见后端列表列.
showSearch List 显示用于搜索记录的输入。默认:false
showSorting List 在每列上显示排序链接。默认:true
defaultSort List 未定义用户首选项时设置默认排序列和方向。支持带键的字符串或数组columndirection.
recordsPerPage List 每页显示的最大行数。
noRecordsMessage List 没有找到记录时显示的消息,可以参考本地化字符串.
conditions List 指定要应用于列表模型查询的原始 where 查询语句。
scope List 指定一个查询范围方法 定义在相关表格模型 始终应用于列表查询。该关系将附加到的模型(即父模型) 作为第二个参数 ($query 是第一个)。
filter List 对过滤器范围定义文件的引用,请参见后端列表过滤器.

这些配置值只能为view 选项。

Option Type Description
showCheckboxes List 在每条记录旁边显示复选框。
recordUrl List 将每个列表记录链接到另一个页面。例如:users/update/:id.这:id 部分替换为记录标识符。
customViewPath List 指定自定义视图路径以覆盖列表使用的部分。
recordOnClick List 单击记录时要执行的自定义 JavaScript 代码。
toolbarPartial Both 对带有工具栏按钮的控制器部分文件的引用。例如:_relation_toolbar.htm.此选项覆盖toolbarButtons 选项。
toolbarButtons Both 要显示的一组按钮。这可以格式化为数组或竖线分隔的字符串,或设置为false不显示按钮。可用的选项是:create,update,delete,add,remove,link, &unlink.例子:add|remove.
此外,您可以通过将此属性设置为关联数组来自定义这些按钮内的文本,键是按钮类型,值是该按钮的文本。例子:create: 'Assign User'.该值还支持翻译。

这些配置值只能为manage 选项。

Option Type Description
title Both 弹出标题,可以参考本地化字符串.
此外,您可以通过将其设置为关联数组来单独自定义每种模式的标题,键是模式,值是显示该模式时使用的标题。例如:form: acme.blog::lang.subcategory.FormTitle.
context Form 正在显示的表单的上下文。可以是字符串或带有键的数组:创建、更新。

关系类型

关系管理器如何显示取决于目标模型中的关系定义。关系类型也将决定配置要求,这些显示在bold.以下关系类型可用:

有很多

  1. 相关记录显示为列表 (view.list).
  2. 单击记录将显示更新表单(manage.form).
  3. 点击Add 将显示一个选择列表(manage.list).
  4. 点击Create 将显示一个创建表单(manage.form).
  5. 点击Delete 将销毁记录。
  6. 点击Remove 将使这种关系成为孤儿。

例如,如果一个博文 有很多Comments,目标模型设置为博客文章并显示评论列表,使用列list 定义。单击评论会打开一个弹出表单,其中包含定义的字段form 更新评论。可以用相同的方式创建评论。下面是关系行为配置文件的示例:

# ===================================
#  Relation Behavior Config
# ===================================

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|delete

属于很多

  1. 相关记录显示为列表 (view.list).
  2. 点击Add 将显示一个选择列表(manage.list).
  3. 点击Create 将显示一个创建表单(manage.form).
  4. 点击Delete 将销毁数据透视表记录。
  5. 点击Remove 将使这种关系成为孤儿。

例如,如果一个User 属于许多Roles,目标模型设置为用户并显示角色列表,使用列list 定义。可以为用户添加和删除现有角色。下面是关系行为配置文件的示例:

# ===================================
#  Relation Behavior Config
# ===================================

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.yaml

属于许多人(使用数据透视表)

  1. 相关记录显示为列表 (view.list).
  2. 单击记录将显示更新表单(pivot.form).
  3. 点击Add 将显示一个选择列表(manage.list),然后是数据输入表单 (pivot.form).
  4. 点击Remove 将销毁数据透视表记录。

继续示例属于许多人 关系,如果一个角色也有一个到期日期,点击一个角色将打开一个弹出表单,其中包含定义的字段pivot 更新到期日期。下面是关系行为配置文件的示例:

# ===================================
#  Relation Behavior Config
# ===================================

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 关系,见下例:

# ===================================
#  Relation Behavior Config
# ===================================

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 color

属于

  1. 相关记录显示为预览形式(view.form).
  2. 点击Create 将显示一个创建表单(manage.form).
  3. 点击Update 将显示一个更新表单(manage.form).
  4. 点击Link 将显示一个选择列表(manage.list).
  5. 点击Unlink 将使这种关系成为孤儿。
  6. 点击Delete 会毁掉记录。

例如,如果一个Phone 属于一个Person 关系经理将显示一个表单,其中包含定义的字段form.单击“链接”按钮将显示要与电话关联的人员列表。单击“取消链接”按钮将取消电话与此人的关联。

# ===================================
#  Relation Behavior Config
# ===================================

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.yaml

有一个

  1. 相关记录显示为预览形式(view.form).
  2. 点击Create 将显示一个创建表单(manage.form).
  3. 点击Update 将显示一个更新表单(manage.form).
  4. 点击Link 将显示一个选择列表(manage.list).
  5. 点击Unlink 将使这种关系成为孤儿。
  6. 点击Delete 会毁掉记录。

例如,如果一个Person 有一个Phone 关系经理将显示带有定义的字段的表单form 电话。单击“更新”按钮时,将显示一个弹出窗口,其中的字段现在可编辑。如果此人已经有电话,则字段会更新,否则会为他们创建一个新电话。

# ===================================
#  Relation Behavior Config
# ===================================

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);

NOTE:形式行为 将在创建、更新和预览操作时自动初始化模型。

然后可以通过调用relationRender 方法。例如,如果您想在Preview 页, 的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';
    }
}

扩展视图小部件

提供操作视图小部件的机会。

NOTE: 视图小部件尚未完全初始化,因此并非所有公共方法都能按预期工作!欲了解更多信息,请阅读如何删除列.

例如,您可能希望根据模型的属性切换 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() 方法,如列表控制器文档 将按预期工作,但要删除列,我们需要在 relationExtendViewWidget() 方法中监听“list.extendColumns”事件。以下示例显示如何删除列:

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;

    // Will not work!
    $widget->removeColumn('my_column');

    // 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.

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'];
}

覆盖关系部分

有时您可能希望覆盖默认关系部分.为此,创建一个与默认部分同名的文件,但在其前面加上_relation 并将其存储在您的控制器目录中。您的部分将被自动检测并使用,而不是默认的。

假设您想覆盖_manage_form.htm 部分的。在您的控制器目录中创建一个文件,并将其命名_relation_manage_form.htm.

豫ICP备18041297号-2