arogachev/yii2-sortable

为 Yii 2 框架提供的可排序 ActiveRecord

安装数: 30,331

依赖者: 6

建议者: 0

安全性: 0

星标: 17

关注者: 3

分支: 9

开放问题: 17

类型:yii2-extension

0.1.6 2016-01-27 03:28 UTC

This package is not auto-updated.

Last update: 2024-09-14 17:00:54 UTC


README

此扩展允许通过不同的行为来管理 ActiveRecord 模型的顺序。选择适合您需求的一个。

Latest Stable Version Total Downloads Latest Unstable Version License

安装

安装此扩展的最佳方式是通过 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>

您可以通过 templatebuttons 属性(类似于 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 - 被移动的模型主键值(如果为主键,则传递对象)