改版前网址:https://my.oschina.net/bubifengyun/blog/605908
上文四、值得完善之处
,发现有改进的可能。后来网站开发需要,有更多的一边是树形结构,一边是表格的形式,用原来的方法,太过粗糙,当然本次改版,也没有逃脱效率低下的困境,唯一的优势是代码量大幅度下降,而且还不惧原来插件的更新。
第十八章 treeview 跟 Gridview 的结合(改版)
参考资料:
一、示例提供的安装教程(前半部分)
如有不明白,可以参照原教程的 1-3 点。
1、安装插件
composer require kartik-v/yii2-tree-manager "@dev"
composer require kartik-v/yii2-grid "@dev"
2、导入数据库
php yii migrate/up --migrationPath=@vendor/kartik-v/yii2-tree-manager/migrations
解释:
- 我是使用 XAMPP 开发的,使用 phpmyadmin 可以更改这个数据库,建议对这个
Tree
数据表添加你需要的属性。
3、建立模型(model)
我是使用 gii 直接导入的这个模型(model),gii 生成后,把原始表的所有字段的验证去掉(此处感谢26056-sjg20010414 )。需要把他的父类修改一下,
namespace common\models;
use Yii;
class Tree extends \kartik\tree\models\Tree
{
/*略*/
}
4、建立模块(module)
'modules' => [
'treemanager' => [
'class' => '\kartik\tree\Module',
// other module settings, refer detailed documentation
]
]
二、结合 GridView 的部分
使用 TreeView 插件,假设现有一个 Personinfo ,对应有 PersoninfoController
的动作,
/**
* Every User take control of Out in special unit.
* @return mixed
*/
public function actionOut()
{
$see_unit = Yii::$app->user->identity->see_unit;
$current_unit = Yii::$app->session->get('current_unit', 0);
if ($current_unit === 0) {
$current_unit = $see_unit;
}
if (Unit::findOne($see_unit) == null) {
throw new NotFoundHttpException('请检查你可以查看的单位范围');
}
// add children and itself.
$query = Unit::findOne($see_unit)
->children()
->orWhere(['id' => $see_unit])
->addOrderBy('root, lft');
return $this->render('out', [
'query' => $query,
'current_unit' => $current_unit,
]);
}
下面说渲染的页面 ./frontend/views/personinfo/out.php,代码如下:
<?php
use yii\helpers\Html;
use yii\helpers\Url;
use kartik\tree\TreeView;
use kartik\tree\Module;
use common\models\Unit;
/* @var $this yii\web\View */
/* @var $model common\models\Personinfo */
$this->title = '外出管理';
$this->params['breadcrumbs'][] = ['label' => '所有人员', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="personinfo-view">
<?= TreeView::widget([
'query' => $query,
'headingOptions' => ['label' => '部别'],
'nodeView' => '@frontend/views/personinfo/_nodeoutgridview',
'nodeActions' => [
Module::NODE_MANAGE => Url::to(['treemanager-router', 'router' => 'out']),
],
'isAdmin' => false,
'rootOptions' => ['label' => '您可以查看的部别'],
'displayValue' => $current_unit,
'toolbar' => [
TreeView::BTN_REFRESH => false,
TreeView::BTN_CREATE => false,
TreeView::BTN_CREATE_ROOT => false,
TreeView::BTN_REMOVE => false,
TreeView::BTN_SEPARATOR => false,
TreeView::BTN_MOVE_UP => false,
TreeView::BTN_MOVE_DOWN => false,
TreeView::BTN_MOVE_LEFT => false,
TreeView::BTN_MOVE_RIGHT => false,
TreeView::BTN_SEPARATOR => false,
],
]) ?>
</div>
解释:
- 其他部分的解释见原文
- 里面有一个特殊的动作,也即
Url::to(['treemanager-router', 'router' => 'out'])
,下面将会介绍。主要由该函数实现原博客粘贴整个模块要实现的功能。位于 ./frontend/controller/PersoninforController.php
use kartik\tree\TreeView;
use kartik\tree\controllers\NodeController;
//** skip many code.
public function actionTreemanagerRouter($router)
{
extract(static::getPostData());
if (isset($id) && !empty($id)) {
Yii::$app->session->set('current_unit', $id);
}
return $this->redirect([$router]);
}
protected static function getPostData()
{
if (empty($_POST)) {
return [];
}
$out = [];
foreach ($_POST as $key => $value) {
$out[$key] = in_array($key, NodeController::$boolKeys) ? filter_var($value, FILTER_VALIDATE_BOOLEAN) : $value;
}
return $out;
}
// skip many code
解释:
- 由于原来插件中
getPostData()
函数是protected
的,无法直接调用,不得已,复制在此。
文中缺少的部分解释,详见原文,此处不再赘述。