arogachev / yii2-sortable
为 Yii 2 框架提供的可排序 ActiveRecord
Requires
Requires (Dev)
- yiisoft/yii2-codeception: ~2.0
This package is not auto-updated.
Last update: 2024-09-14 17:00:54 UTC
README
此扩展允许通过不同的行为来管理 ActiveRecord 模型的顺序。选择适合您需求的一个。
安装
安装此扩展的最佳方式是通过 composer。
运行以下命令之一
php composer.phar require --prefer-dist arogachev/yii2-sortable
或在您的 composer.json
文件的 require 部分添加
"arogachev/yii2-sortable": "*"
到您的 composer.json
文件。
功能
- 实现了几个算法。选择一个适合您需求的。
- 设置可排序范围。在这种情况下,每个范围内的模型顺序是独立管理的。
- 可排序条件的额外设置。例如,如果模型可以被标记为活动或已删除,您可以额外指定该条件,并在更改这些属性值时考虑它。
- 添加新模型、移除出可排序范围或在不同可排序范围之间移动时自动调整顺序。
- 在可排序范围内更改模型顺序。
- 用于管理
GridView
中模型顺序的 GUI(《可排序列》)。 - 简化编写自定义 GUI 的排序控制器
行为类型
有几个行为可供选择
ContinuousNumericalSortableBehavior
IntervalNumericalSortableBehavior
LinkedListSortableBehavior
(目前未实现)
前两个是数值行为,它们有一个共同点 - 将每个模型的顺序存储为数字。
ContinuousNumericalSortableBehavior
:
存储的数字等于确切的位置。
优点
- 您可以在不进行额外查询的情况下获取当前位置
缺点
- 根据可排序模型的数量和情况,
UPDATE
查询的数量可能很大。这涉及到调整顺序。例如,在切换位置为 3 和 4 的模型时,不会执行额外查询(只有 2 个UPDATE
查询)。但如果有 1000 个模型,并将最后一个模型移至最前面,将会有 1000 个UPDATE
查询(因此这取决于间隔长度)。
IntervalNumericalSortableBehavior
:
数字以一定间隔存储(最初大小相等)。您可以在这里查看使用的算法的基本描述。
优点
- 对于添加或删除,无需调整其他模型的顺序。对于大多数情况,更改顺序通常只需执行几个
SELECT
和一个UPDATE
查询。仅在发生冲突时才需要调整可排序范围内所有模型的顺序。如果间隔大小足够大,并且不反复将模型移动到相同的位置,则冲突不会经常发生。
缺点
- 为了获取模型的顺序,使用额外的查询。
准备表结构
在数值行为中使用时,将其添加到迁移中
$this->addColumn('table_name', 'sort', Schema::TYPE_INTEGER . ' NOT NULL');
附加行为
将其添加到您的模型中以进行最小设置
use arogachev\sortable\behaviors\numerical\ContinuousNumericalSortableBehavior;
/** * @inheritdoc */ public function behaviors() { return [ [ 'class' => ContinuousNumericalSortableBehavior::className(), ], ]; }
配置行为
所有行为共有的属性
scope
- 可排序范围。如果您想根据条件分离模型并独立在每个范围内管理顺序,则指定它。它期望返回 ActiveQuery
的闭包,但 where
部分必须以数组的形式指定。例如
function () { return Question::find()->where(['test_id' => $this->test_id]); }
您可以使用 $model
参数生成与模型相关的查询
function ($model) { return $model->getNeighbors(); }
其中 getNeighbors()
的实现可以是这样
/** * @return \yii\db\ActiveQuery */ public function getNeighbors() { return static::find()->where(['parent_id' => $this->parent_id]); }
如果这个属性未设置,所有模型将被视为一个可排序的范围。
sortableCondition
- 一个额外的属性,用于过滤可排序模型。您应该将其指定为条件数组
[ 'is_active' => 1, 'is_deleted' => 0, ],
prependAdded
- 将添加的可排序模型插入到可排序范围的开始位置。默认为 false
,这意味着插入到末尾。
access
- 用于检查当前用户对排序访问权限的闭包。示例
function () { return Yii::$app->user->can('questions.sort'); }
数值行为属性
sortAttribute
- 排序属性列的名称。默认为 sort
。
IntervalNumericalSortableBehavior
属性
intervalSize
- 区间大小。默认为 1000
。指定较大的数字时,冲突发生的频率会更低。
increasingLimit
- 用户可以将项目连续移动到可排序范围末尾的次数。用于防止数字的增加。默认为 10
。
在可排序范围内更改模型顺序
该行为提供了几个方法来更改任何可排序模型的顺序
moveToPosition($position)
- 将模型移动到可排序范围内的任何位置的基方法moveBefore($pk = null)
- 将模型移动到本可排序范围中的另一个模型之前。如果未指定$pk
,则将其移动到末尾moveAfter($pk = null)
- 将模型移动到本可排序范围中的另一个模型之后。如果未指定$pk
,则将其移动到开头moveBack()
- 向后移动一个位置moveForward()
- 向前移动一个位置moveAsFirst()
- 移动到开头moveAsLast()
- 移动到末尾
用于更改顺序的 GUI
对于 GridView
,存在特殊的 SortableColumn
。
功能
- 它不会强制您使用整个另一个
GridView
- 无需每次都附加额外的操作
- 支持单页上的多个
GridView
- 显示当前位置
- 当前位置的在线编辑
- 通过拖放(使用
jQuery UI Sortable
)进行移动,带有特殊的处理图标,因此您可以在不触发排序更改的情况下与其他数据交互 - 向后和向前移动一个位置
- 移动到第一和最后
将此包含到您的应用程序配置中
'controllerMap' => [ 'sort' => [ 'class' => 'arogachev\sortable\controllers\SortController', ], ],
然后配置 GridView
- 用
Pjax
小部件包裹它,以实现无需页面刷新的工作 - 为不可更改的根容器添加
id
- 在
columns
部分包含列
use arogachev\sortable\grid\SortableColumn;
<div class="question-index" id="question-sortable"> <?php Pjax::begin(); ?> <?= GridView::widget([ // Other configuration 'columns' => [ [ 'class' => SortableColumn::className(), 'gridContainerId' => 'question-sortable', 'baseUrl' => '/sort/', // Optional, defaults to '/sort/' 'confirmMove' => true, // Optional, defaults to true ], // Other columns ], ]) ?> <?php Pjax::end(); ?> </div>
您可以通过 template
和 buttons
属性(类似于 ActionColumn)来配置显示。
可用的标签有
currentPosition
moveWithDragAndDrop
moveForward
moveBack
moveAsFirst
moveAsLast
您可以通过自己的方式扩展它。覆盖示例
'template' => '<div class="sortable-section">{moveWithDragAndDrop}</div> <div class="sortable-section">{currentPosition}</div> <div class="sortable-section">{moveForward} {moveBack}</div>', 'buttons' => [ 'moveForward' => function () { return Html::tag('i', '', [ 'class' => 'fa fa-arrow-circle-left', 'title' => Yii::t('sortable', 'Move forward'), ]); }, 'moveBack' => function () { return Html::tag('i', '', [ 'class' => 'fa fa-arrow-circle-right', 'title' => Yii::t('sortable', 'Move back'), ]); }, ],
自定义用于更改顺序的 GUI
如果您想编写自己的GUI来更改顺序而不使用 GridView
,可以使用 SortController
动作
move-before
(需要通过POST
发送的下一个元素的pk
)move-after
(需要通过POST
发送的移动后前一个元素的pk
)move-back
move-forward
move-as-first
move-as-last
move-to-position
(需要通过POST
发送的position
)
对于所有这些操作,这两个参数必须在 POST
中存在
modelClass
- 模型完整类名,包括命名空间modelPk
- 被移动的模型主键值(如果为主键,则传递对象)