# 组件
## 组件
### 组件说明
- 组件文件所在目录 /plugins/用户名/插件名/components
- 每个组件都有一个定义组件类的PHP文件和一个可选的组件partials目录。
- 组件的partials目录名称与以小写形式编写的组件类名称匹配。
- 组件目录结构的示例:
```
plugins/
用户名/
myplugin/
components/
componentname/ <=== Component partials directory
default.htm <=== Component default markup (optional)
ComponentName.php <=== Component class file
Plugin.php
```
必须使用该方法将组件[注册在Plugin注册类中](https://octobercms.com/docs/plugin/components#component-registration)`registerComponents`。
### 组件注册
- 必须通过重写`Plugin注册类中`的`registerComponents`方法来注册组件。
- 注册组件的示例:这将使用默认别名名称**demoTodo**注册Todo组件类
```
public function registerComponents()
{
return [
'October\Demo\Components\Todo' => 'demoTodo'
];
}
```
### 组件类定义
- **组件类文件**定义了组件功能和组件的属性
- 组件类文件名应与组件类名匹配
- 组件类应继承扩展`\Cms\Classes\ComponentBase`该类。
- 定义组件详情的`componentDetails`方法是必需的。该方法应返回带有两个键的数组:`name`和`description`。名称和描述显示在CMS后端用户界面中。
- 示例: `componentDetails`定义属性,`posts`定义方法
```
namespace Acme\Blog\Components;
class BlogPosts extends \Cms\Classes\ComponentBase
{
public function componentDetails()
{
return [
'name' => 'Blog Posts',
'description' => 'Displays a collection of blog posts.'
];
}
// This array becomes available on the page as {{ component.posts }}
public function posts()
{
return ['First Post', 'Second Post', 'Third Post'];
}
}
```
- 当组件附加到页面或布局时,类属性和方法将通过component变量在页面上可用,该变量与组件的短名称或别名匹配。例如,如果示例中的BlogPost组件是在其短名称页面上定义的:
```
url = "/blog"
[blogPosts]
==
```
您将可以`posts`通过`blogPosts`变量访问其方法。请注意,Twig支持方法的属性表示法,因此您无需使用方括号。
```
{% for post in blogPosts.posts %}
{{ post }}
{% endfor %}
```
### 组件属性
- 将组件添加到页面或布局时,可以使用属性对其进行配置
- 这些属性是使用`defineProperties`组件类的方法定义的。下一个示例显示如何定义组件属性:
```
public function defineProperties()
{
return [
'maxItems' => [
'title' => 'Max items',
'description' => 'The most amount of todo items allowed',
'default' => 10,
'type' => 'string',
'validationPattern' => '^[0-9]+$',
'validationMessage' => 'The Max Items property can contain only numeric symbols'
]
];
}
```
- 该方法应返回一个数组,其中属性键为索引,属性参数为值。
- 属性键用于访问组件类内部的组件属性值。使用带有以下键的数组定义属性参数:
| 键 | 描述 |
| --- | --- |
| **title** | 必填属性标题,由CMS后端中的组件检查器使用。 |
| **description** | 必需的属性描述,由CMS后端中的组件检查器使用。 |
| **default** | 可选,将组件添加到CMS后端中的页面或布局时使用的默认属性值。 |
| **type** | 可选,指定属性类型。类型定义了属性在检查器中的显示方式。当前支持的类型是**字符串**,**复选框**,**下拉列表**和**设置**。默认值:**字符串**。(**string**,**checkbox**,**dropdown**and**set**. Default:**string**.) |
| **validationPattern** | 用户在检查器中输入属性值时使用的可选正则表达式。验证只能与**字符串**属性一起使用。 |
| **validationMessage** | 验证失败时显示的可选错误消息。 |
| **required** | 可选,强制填写字段。留空时使用validationMessage。 |
| **placeholder** | 字符串和下拉列表属性的可选占位符。 |
| **options** | 下拉属性的可选选项数组。 |
| **depends** | 下拉属性所依赖的属性名称数组。请参阅下面的[下拉属性](#dropdown-properties)。 |
| **group** | 可选的组名。小组在Inspector中创建部分,以简化用户体验。在多个属性中使用相同的组名将它们组合在一起。 |
| **showExternalParam** | 指定检查器中属性的“外部参数”编辑器的可见性。默认值:**true**。在组件内部,您可以使用以下`property`方法读取属性值: |
```
$this->property('maxItems');
```
如果未定义属性值,则可以提供默认值作为方法的第二个参数`property`:
```
$this->property('maxItems', 6);
```
您还可以将所有属性加载为数组:
```
$properties = $this->getProperties();
```
要从Twig局部访问组件的属性,请使用`__SELF__`引用Component对象的变量:
`{{ __SELF__.property('maxItems') }}`
### 下拉菜单和设置属性
- 下拉菜单和设置属性的选项列表可以是静态的或动态的
- 静态选项是使用`options`属性定义的元素定义的。例:
```
public function defineProperties()
{
return [
'units' => [
'title' => 'Units',
'type' => 'dropdown',
'default' => 'imperial',
'placeholder' => 'Select units',
'options' => ['metric'=>'Metric', 'imperial'=>'Imperial'] //定义静态选项
]
];
}
```
- 如果上面方法返回数组没有`options`键,则选项列表被视为动态列表。
- 组件类必须定义一个返回选项列表的方法。该方法的名称应采用以下格式:`get*Property*Options``get属性名Options`
- 如:`getCountryOptions`该方法返回一个选项数组,其中选项值作为键,选项标签作为值
- 示例:
```
public function defineProperties()
{
return [
'country' => [
'title' => 'Country',
'type' => 'dropdown',
'default' => 'us'
]
];
}
public function getCountryOptions()
{
return ['us'=>'United states', 'ca'=>'Canada'];
}
```
动态下拉列表和设置列表可能取决于其他属性。例如,州列表可能取决于所选国家。依赖项`depends`在属性定义中用参数声明。下一个示例定义了两个动态下拉列表属性,状态列表取决于国家/地区:
```
public function defineProperties()
{
return [
'country' => [
'title' => 'Country',
'type' => 'dropdown',
'default' => 'us'
],
'state' => [
'title' => 'State',
'type' => 'dropdown',
'default' => 'dc',
'depends' => ['country'],
'placeholder' => 'Select a state'
]
];
}
```
为了加载状态列表,您应该知道检查器中当前选择的国家。检查器将所有属性值POST到`getPropertyOptions`处理程序,因此您可以执行以下操作:
```
public function getStateOptions()
{
$countryCode = Request::input('country'); // Load the country property value from POST
$states = [
'ca' => ['ab'=>'Alberta', 'bc'=>'British columbia'],
'us' => ['al'=>'Alabama', 'ak'=>'Alaska']
];
return $states[$countryCode];
}
```
### 页面列表属性
- 有时组件需要创建指向网站页面的链接。例如,博客文章列表包含指向博客文章详细信息页面的链接
- October包含一个用于创建动态下拉列表的帮助器
- 下一个示例定义了postPage属性,该属性显示页面列表:
```
public function defineProperties()
{
return [
'postPage' => [
'title' => 'Post page',
'type' => 'dropdown',
'default' => 'blog/post'
]
];
}
public function getPostPageOptions()
{
return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
```
### 路由参数
- 组件可以直接访问页面URL中定义的路由参数值。
```
// Returns the URL segment value, eg: /page/:post_id
$postId = $this->param('post_id');
```
- 在某些情况下,组件属性可以充当硬编码值或从URL引用该值。
- 这个硬编码示例显示了使用标识符的博客帖子`2`:
```
url = "/blog/hard-coded-page"
[blogPost]
id = "2"
```
- 也可以使用外部属性值从页面URL动态引用该值
```
url = "/blog/:my_custom_parameter"
[blogPost]
id = "{{ :my_custom_parameter }}"
```
- 在这两种情况下,都可以使用以下`property`方法来检索值:
```
$this->property('id');
```
- 如果需要访问路由参数名称:
```
$this->paramName('id'); // Returns "my_custom_parameter"
```
### 处理页面执行周期
通过重写`onRun`组件类中的方法,组件可以参与Page执行周期事件。每次加载页面或布局时,CMS控制器都会执行此方法。在方法内部,您可以通过`page`属性将变量注入页面:
```
public function onRun()
{
// This code will be executed when the page or layout is
// loaded and the component is attached to it.
$this->page['var'] = 'value'; // 向页面中注入一些变量
}
```
### 页面执行生命周期处理程序
页面加载时,October执行可以在布局和页面PHP部分以及组件类中定义的处理程序函数。处理程序的执行顺序如下:
1. 布局`onInit()`功能。
2. 页面`onInit()`功能。
3. 布局`onStart()`功能。
4. 布局组件`onRun()`方法。
5. 布局`onBeforePageStart()`功能。
6. 页面`onStart()`功能。
7. 页面组件`onRun()`方法。
8. 页面`onEnd()`功能。
9. 布局`onEnd()`功能。
### 组件初始化
- 初始化方法是在首次实例化组件类时执行代码。
- 重写`init`组件类中的方法以处理任何初始化逻辑,都将在AJAX处理程序之前和页面执行生命周期之前执行。
- 此方法可用于将另一个组件动态附加到页面。
```
public function init()
{
$this->addComponent('Acme\Blog\Components\BlogPosts', 'blogPosts');
}
```
### 停止回应
- 如果`onRun`组件中的方法返回一个值,后停止该周期并将响应返回给浏览器。可以使用`Response`返回拒绝访问的消息:
```
public function onRun()
{
if (true) {
return Response::make('Access denied!', 403);
}
}
```
您还可以从`onRun`方法返回404响应:
```
public function onRun()
{
if (true) {
$this->setStatusCode(404);
return $this->controller->run('404');
}
}
```
### AJAX处理程序
- 组件托管AJAX事件处理程序与在页面或布局代码中定义的方式完全相同
- 在组件类中定义的示例AJAX处理程序方法:
```
public function onAddItem()
{
$value1 = post('value1');
$value2 = post('value2');
$this->page['result'] = $value1 + $value2;
}
```
- 如果此组件的别名为\*demoTodo,\*则可以通过访问此处理程序`demoTodo::onAddItem`。
- 有关将AJAX与组件一起使用的详细信息,请参见[在组件](https://octobercms.com/docs/ajax/handlers#calling-handlers)文章中[定义](https://octobercms.com/docs/ajax/handlers#calling-handlers)的“[调用AJAX处理程序”](https://octobercms.com/docs/ajax/handlers#calling-handlers)。
### 默认标记
- 所有组件都可以带有默认标记,默认标记是将其包含在带有`{% component %}`标签的页面上时使用的
- 默认标记保存在**组件partials目录中**,该**目录**与小写的组件类同名。
- 默认组件标记应放置在名为**default.htm**的文件中。
- 例如,在文件\*\*/plugins/october/demo/components/todo/default.htm中\*\*定义了Demo ToDo组件的默认标记。然后可以使用`{% component %}`标签将其插入页面上的任何位置:
```
url = "/todo"
[demoTodo]
==
{% component 'demoTodo' %}
```
默认标记还可以采用在渲染[组件](https://octobercms.com/docs/plugin/components#component-properties)时覆盖[组件属性的](https://octobercms.com/docs/plugin/components#component-properties)参数。
```
{% component 'demoTodo' maxItems="7" %}
```
这些属性将在`onRun`方法中不可用,因为它们是在页面循环完成之后建立的。相反,可以通过重写`onRender`组件类中的方法来处理它们。CMS控制器在呈现默认标记之前执行此方法。
```
public function onRender()
{
// This code will be executed before the default component
// markup is rendered on the page or layout.
$this->page['var'] = 'Maximum items allowed: ' . $this->property('maxItems');
}
```
### 零件:入分页
- 分页目录:**/plugins/october/demo/components/todo/pagination.htm中,**
- 使用以下命令在页面上显示:
```
{% partial 'demoTodo::pagination' %}
```
- 如果在组件局部内部调用,它将直接引用自身
- 如果在主题部分中调用,它将扫描页面/布局上使用的所有组件以查找匹配的部分名称并使用该名称。
```
{% partial '@pagination' %}
```
- 多个组件可以通过将部分文件放置在名为**components / partials**的目录中来共享**部分**。
- 如果找不到常用的组件零件,则在此目录中找到的局部用作备用。
- 例如,任何组件都可以使用以下命令在页面上显示\*\*/plugins/acme/blog/components/partials/shared.htm中\*\*的共享部分:
```
{% partial '@shared' %}
```
### 引用“自我”
组件可以使用该`__SELF__`变量在自己的部分中引用自己。默认情况下,它将返回组件的简称或[别名](https://octobercms.com/docs/cms/components#aliases)。
```
<form data-request="{{__SELF__}}::onEventHandler">
[...]
</form>
```
组件也可以引用自己的属性。
```
{% for item in __SELF__.items() %}
{{ item }}
{% endfor %}
```
如果在部件局部内部,则需要渲染另一个部件局部`__SELF__`,以部分名称连接变量:
```
{% partial __SELF__~"::screenshot-list" %}
```
### 唯一标识符
如果在同一页面上两次调用相同的组件,`id`则可以使用属性来引用每个实例。
```
{{__SELF__.id}}
```
每次显示组件时,ID都是唯一的。
```
<!-- ID: demoTodo527c532e9161b -->
{% component 'demoTodo' %}
<!-- ID: demoTodo527c532ec4c33 -->
{% component 'demoTodo' %}
```
### 渲染主键
- `renderPartial`方法渲染组件,渲染后将结果作为字符串返回
- 第一个方法:组件文件`component-partial.htm`
- 第二个参数用于传递视图变量。
```
$content = $this->renderPartial('component-partial.htm');
$content = $this->renderPartial('component-partial.htm', [
'name' => 'John Smith'
]);
```
例如,将部分渲染为对[AJAX处理程序](https://octobercms.com/docs/ajax/handlers)的响应:
```
function onGetTemplate()
{
return ['#someDiv' => $this->renderPartial('component-partial.htm')];
}
```
另一个示例可能是通过返回`onRun`渲染页面的结果来覆盖整个页面视图响应。这段代码将使用`Response`Facade专门返回XML响应:
```
public function onRun()
{
$content = $this->renderPartial('default.htm');
return Response::make($content)->header('Content-Type', 'text/xml');
}
```
### 向页面注入组件
- 组件可以将资源(CSS和JavaScript文件)注入到它们所附着的页面或布局中
- 使用控制器的`addCss`和`addJs`方法将资产添加到CMS控制器。
- 可以用组件的`onRun`方法完成
- 例:
```
public function onRun()
{
$this->addJs('/plugins/acme/blog/assets/javascript/blog-controls.js');
}
```
- 如果`addCss`and`addJs`方法参数中指定的路径以斜杠(/)开头,则它将相对于网站根目录。如果资源路径不是以斜杠开头,则它是相对于组件目录的。
- `addCss`和`addJs`方法提供了您的注入资源的属性定义为一个阵列的第二个参数。有一个特殊的属性--`build`可以为您注入的资源添加指定版本的当前插件后缀。插件升级后,可用于刷新缓存的资产。
```
public function onRun()
{
$this->addJs('/plugins/acme/blog/assets/javascript/blog-controls.js', [
'build' => 'Acme.Test',
'defer' => true
]);
}
```
您也可以使用字符串作为第二个参数,然后默认使用字符串值作为`build`:
```
public function onRun()
{
$this->addJs('/plugins/acme/blog/assets/javascript/blog-controls.js', 'Acme.Test');
}
```
- 基本说明
- 基本操作
- October cms 安装
- 后台控制器路径
- 图标
- 获取安装网上的插件/主题
- 插件构造器使用
- 定时任务
- October后台控制器
- vscode编辑器
- ajax操作
- 使用
- ajax更新组件
- ajax属性API
- JavaScript API
- ajax综合使用
- 主题
- 多语言主题
- 安装市场主题
- 主题程序处理
- 主题
- 页面
- 部件
- 布局
- 内容
- 组件
- 媒体
- 主题表单操作
- 表单使用
- 表单后端程序处理
- 插件
- 自定义插件
- 插件说明
- 插件导航条
- 插件数据库设置
- 插件的设置管理
- 插件的配置文件config
- 组件
- app服务
- app容器
- 扩展行为
- 缓存
- Collection类
- Lazy Collections
- Collection方法
- 助手函数
- 数组助手函数
- 路径助手函数
- 玄乐助手函数
- 其他助手函数
- 错误与记录
- 事件处理
- HTML页面
- 文件与目录操作
- 散列和加密
- 邮件
- 邮件内容
- 邮件发送
- 分页
- 模板解析器
- 动态解析器语法
- 队列消息
- 请求与输入
- 响应
- 视图
- 路由器
- 配置
- 验证操作
- 处理错误消息
- 错误消息与视图
- 可用的验证规则
- 有条件的验证规则
- 验证数组
- 错误消息
- 自定义验证规则
- 模型操作
- 定义模型与其属性
- 检索模型
- 插入与更新
- 删除模型
- 查询范围
- 事件操作
- 关联操作
- 定义关系
- 关系类型
- 多肽关系
- 关系查询
- 渴望加载
- 插入模型
- 数据库操作
- 基本用法
- 数据表结构
- 查询连贯操作
- 结果检索
- select子句
- 插入更新
- where子句
- 排序,分组,限制和偏移
- 文件附件
- Collection操作
- 属性操作
- 系列化json
- 数据库属性
- 数据库行为
- 控制器
- 后台控制器定义
- 后台页面
- 后台组件
- 后台表单
- 表单组件
- 表单视图
- 表单行为
- 后台列表
- 列表行为
- 列表过滤器
- 可用列类型
- 关系行为
- 关系行为类型
- 扩展关系行为
- 列表排序操作
- 导入导出操作
- 用于与权限
- corlate模板修改
- 修改顶部导航
- laravel问题
- 控制器不存在
- 控制器
- 路由组
- laravel笔记
- laravel 安装
- 伪静态配置
- 依赖注入 & 控制器
- 中间件
- 路由文件
- 视图