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 的排序控制器
行为类型
有几个行为可供选择
ContinuousNumericalSortableBehaviorIntervalNumericalSortableBehaviorLinkedListSortableBehavior(目前未实现)
前两个是数值行为,它们有一个共同点 - 将每个模型的顺序存储为数字。
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)来配置显示。
可用的标签有
currentPositionmoveWithDragAndDropmoveForwardmoveBackmoveAsFirstmoveAsLast
您可以通过自己的方式扩展它。覆盖示例
'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-backmove-forwardmove-as-firstmove-as-lastmove-to-position(需要通过POST发送的position)
对于所有这些操作,这两个参数必须在 POST 中存在
modelClass- 模型完整类名,包括命名空间modelPk- 被移动的模型主键值(如果为主键,则传递对象)