一边treeview一边girdview结合的页面 [ 2.0 版本 ]
title: yii2开发网站流程
author: 不避风云
date: '2016-01-22'
identifier:
- scheme: ISBN
text: xxxxxxxxxx
publisher: 不告诉你
category: '计算机网站开发:
Yii2开发网站记录'
chapter: '18'
pages: 004-019
本文网址:http://my.oschina.net/bubifengyun/blog/605908
第十八章 treeview跟Gridview的结合
一、功能设想
yii2做的网站,一边是树形结构treeview,一边是表格列表gridview,利用kartik的插件,这两个都比较容易搭建起来。选择左边的treeview,根据不同的选择项,girdview显示对应节点的信息。这个功能具有较好的使用价值。
二、参考资料
- https://github.com/neattutorials/yii2-pjax-examples
- http://blog.neattutorials.com/yii2-pjax-tutorial/
- https://github.com/kartik-v/yii2-tree-manager
- http://demos.krajee.com/tree-manager
- https://github.com/kartik-v/yii2-grid
三、完成步骤
总共花了两周时间才完成,中间查了很多资料,不一一记录了。由于时间较长,可能部分内容缺失,如果无法工作,欢迎在下面留言。总体流程是如下:安装tree manager的treeview,=》对treeview显示内容进行改动,=》把显示内容更改为gridview,=》修复gridview出现的各种问题。
1、安装tree manager 和 girdview
composer require kartik-v/yii2-tree-manager "@dev"
composer require kartik-v/yii2-grid "@dev"
2、数据库的导入
找到./vendor/kartik-v/yii2-tree-manager/schema/tree.sql
文件,由于本人是xampp开发,使用phpmyadmin,
进入到工作用的db_lhpg
,点击导入按钮,选择该文件导入即可。导入后,可以根据自己需要在tbl_tree
添加部分项,或者修改部分备注。
最好不要删除原有的项。我把添加好的tbl_tree
更名为tbl_unit
了,没有做任何添加。
3、创建模型Model
可以使用gii自动生成工具,Model命名空间为common/models
。修改./common/models/Unit.php
文件(对应你生成的文件),修改内容如下。
namespace common\models;
use Yii;
class Tree extends \kartik\tree\models\Tree
{
/*略*/
}
4、创建Module
这部分内容比较多。
- 创建文件夹modules,
mkdir ./frontend/modules
- 复制模块内容到modules文件夹,
cp -r ./vendor/kartik-v/yii2-tree-manager ./frontend/modules/tree
- 把
./frontend/modules/tree
文件夹下所有.php文件的命名空间namespace kartik\tree
改为namespace frontend\modules\tree
;
包括那些namespace kartik\tree\controllers
等类似的命名空间。 - 修改配置文件
./frontend/config/main.php
,加入如下内容。
'modules' => [
'treemanager' => [
'class' => '\frontend\modules\tree\Module',
]
]
5、使用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;
// add children and itself.
$query = Unit::findOne($see_unit)
->children()
->orWhere(['id' => $see_unit])
->addOrderBy('root, lft');
$current_unit = Yii::$app->session->get('current_unit', 0);
if ($current_unit === 0){
$current_unit = $see_unit;
}
return $this->render('out', [
'query' => $query,
'current_unit' => $current_unit,
]);
}
解说:
- 网站通过http://localhost/www/wuzhishan/frontend/web/index.php?r=personinfo%2Fout访问
- 由于是针对特定用户有特定的查看权限,所以首先获取查看权限
$see_unit
$query
是提供给TreeView使用的变量.children()
函数见yii2-nested-sets的说明。$current_unit
是当前正在查看的变量。- 这里如果
$current_unit
不在可查看权限$see_unit
的权限范围内的话,是0或者其他数值,则只显示根目录的数值。 - 需要特别说明的是
Yii::$app->session->get('current_unit', 0);
用于每次刷新,把上次点击的内容复制过来。也就是需要其他地方设置
Yii::$app->session->set('current_unit', $current_unit);
这个在下面说。
下面说渲染的页面./frontend/views/personinfo/out.php
,代码如下:
<?= TreeView::widget([
'query' => $query,
'headingOptions' => ['label' => '部别'],
'nodeView' => '@frontend/views/personinfo/_nodegridview',
'nodeActions' => [
Module::NODE_MANAGE => Url::to(['/treemanager/node/my-manage']),
],
'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,
],
]) ?>
解说:
$query
见controller传过来的变量。- 这里对
nodeView
重新赋值了。为@frontend/views/personinfo/_nodegridview
,请一定把路径写完,否则无法找到该页面。 nodeActions
只修改了NODE_MANAGE
,经多轮测试,一直没有找到好的解决方案,只好修改Module里源代码了,这也是把原来Module内置到frontend的原因。toolbar
被禁用了,但是还是那么操蛋,必须要一个个的赋值为false才可以。- 有不懂的请参考该插件的文档:http://demos.krajee.com/tree-manager
Module::NODE_MANAGE => Url::to(['/treemanager/node/my-manage'])
中的my-manage
的解说,
在 ./frontend/modules/tree/controllers/NodeController.php
文件中,
该动作对应于actionMyManage
函数。内容如下。
/**
* View a tree node via ajax
*
* @return redirect to `/personinfo/out`
*/
public function actionMyManage()
{
extract(static::getPostData());
if (isset($id) && !empty($id)) {
Yii::$app->session->set('current_unit', $id);
}
return $this->redirect(['/personinfo/out']);
}
解说:
- 这个是一种折中做法,本来希望
Module::NODE_MANAGE => Url::to(['/frontend/personinfo/out'])
的,但是各种调试失败,做了如下折中。
首先读取$_POST
的内容,主要是点击TreeView树形结构节点Node获得id
,然后刷新网页['/personinfo/out']
,
把获得的id
传递过去,传递方式采用的session方式。
下面把./frontend/views/personinfo/_nodegridview.php
的内容贴出来。
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\widgets\Pjax;
use kartik\grid\GridView;
use kartik\tree\TreeView;
use common\models\Personinfo;
use common\models\PersoninfoSearch;
use common\models\Unit;
/* @var $this yii\web\View */
/* @var $model common\models\Personinfo */
/* @var $form yii\widgets\ActiveForm */
Pjax::begin();
// run every key=>value as variant in PHP.
extract($params);
$children = Unit::findOne($node->id)->children()->all();
$selfAndChildrenID = [$node->id];
foreach($children as $child){
$selfAndChildrenID[] = $child->id;
}
$searchModel = new PersoninfoSearch();
$searchModel->unit_code = $selfAndChildrenID;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
echo GridView::widget([
'id' => 'admin-gridview-id',
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'class' => 'kartik\grid\SerialColumn'
],
'name',
'is_married',
'can_home_weekend',
'mil_rank',
[
'class' => 'kartik\grid\ActionColumn',
'template' => '{view}{update}',
],
],
'containerOptions' => ['style'=>'overflow: auto'], // only set when $responsive = false
'toolbar' => [
'{export}',
'{toggleData}'
],
'pjax' => true,
'bordered' => true,
'striped' => false,
'condensed' => false,
'responsive' => true,
'hover' => true,
// 'floatHeader' => true,
// 'floatHeaderOptions' => ['scrollingTop' => $scrollingTop],
'showPageSummary' => true,
'panel' => [
'type' => GridView::TYPE_PRIMARY
],
]);
Pjax::end();
解说:
params
是通过动作传过来的一个变量,知道内有一个node
就可以了,node
是Unit
的一个实例或者说是一个对象。$searchModel->unit_code = $selfAndChildrenID;
设置该语句的时候,其中$selfAndChildrenID
是数组array。
需要设置searchPersoninfo
的rules
的规则,unit_code
是safe
。Yii2会实现自动搜索所有归属这些单位的人员。- 其他解释见文档:https://github.com/kartik-v/yii2-grid 及相关说明。
调试发现,每次点击gridview的排序,都没有任何东西放在post变量里,这个问题需要好好解决。
这样就实现了一边是树形结构TreeView,一边是表格GridView,且GirdView可以调节改动。可以根据自己的需要,排序搜索GridView的内容。
四、值得完善之处
在花费两周的时间才解决这个问题时,设想了很多方案,比如把原作者的这个模块给肢解了,各自放到frontend里。
当然最好的方案是把这个模块留在./vendor
文件夹里,不需要对他做任何改动。只是修改
Module::NODE_MANAGE => Url::to(['/frontend/personinfo/out']),
,然后配置一下Controller里的ActionOut函数。
由于缺乏时间对此进行更深的研究,先留存在这里。
五、贴一张图来过过瘾。
六、源代码
网站正在紧锣密鼓的开发中,后期会开源。
bubifengyun NJSH
最后登录:2022-10-29
在线时长:59小时54分
- 粉丝36
- 金钱10
- 威望160
- 积分2200
共 5 条评论
能不能把你的module配置贴出来看看啊!谢谢
哪里不懂?可以加qq402229566或者在https://github.com/bubifengyun/book-yii2-dev-process/blob/master/src/ch-18.md发issue
@bubifengyun 谢谢你了 解决了
这个可能更换表结构么?
哪个表?是树形结构的表嘛?这个可以在原来树形表格中添加很多属性的。原来自带的不建议删除,保留即可。
哪个表?是树形结构的表嘛?这个可以在原来树形表格中添加很多属性的。原来自带的不建议删除,保留即可。
@bubifengyun 好的,谢谢
打算对该模块进行升级,现在测试成功,等待后续更改。
你好请问表中字段 lft 和 rgt 分别有什么作用
如果只是为了排序的话,那么只需要一个权重字段即可
一直想不明白求大神指导
看完这个 顿悟
http://www.w3dev.cn/article/20130709/hierarchical-data-Nested-Set.aspx
谢谢,你还专门去查找了。我打算对这个博客更新,可以使用一个较为简单的方法来实现这个界面,最近两三个星期会更新吧,到时候把你这个链接加进去。如果有啥好的建议,欢迎留言。
有问题欢迎留言,谢谢啦。