首页 > 解决方案 > Yii2 显示/隐藏kartik树视图节点

问题描述

我正在使用Kartik 树管理器。我能够添加、删除、更新节点。还有更多要求,即根据用户访问权限显示/隐藏节点。即,当给用户一个特定节点时,只应显示具有所有子节点(如果有)的特定节点。

到目前为止我做了什么?

我创建了一个表user-node,我在其中将节点 ID 分配给用户,如下所示

在此处输入图像描述

我想做的事

现在我只想显示指定节点及其子节点,并向该用户隐藏其他节点

在此处输入图像描述

控制器

目前,我正在渲染树结构的视图有两种,但将来会更多

  1. 我的首页

    public function actionIndex()
    {
       if(Yii::$app->user->isGuest){
        $this->redirect(Yii::$app->urlManager->createUrl('site/login'));
        }
       return $this->render('index');
    }
    
  2. 本身树管理器节点控制器

    /**
    * View, create, or update a tree node via ajax
    *
    * @return mixed json encoded response
    */
    public function actionManage()
    {
        static::checkValidRequest();
        $data = static::getPostData();
        $nodeTitles = TreeSecurity::getNodeTitles($data);
        $callback = function () use ($data, $nodeTitles) {
        $id = ArrayHelper::getValue($data, 'id', null);
        $parentKey = ArrayHelper::getValue($data, 'parentKey', '');
        $parsedData = TreeSecurity::parseManageData($data);
        $out = $parsedData['out'];
        $oldHash = $parsedData['oldHash'];
        $newHash = $parsedData['newHash'];
        /**
         * @var Module $module
         * @var Tree $treeClass
         * @var Tree $node
         */
        $treeClass = $out['treeClass'];
        if (!isset($id) || empty($id)) {
            $node = new $treeClass;
            $node->initDefaults();
        } else {
            $node = $treeClass::findOne($id);
        }
        $module = TreeView::module();
        $params = $module->treeStructure + $module->dataStructure + [
                'node' => $node,
                'parentKey' => $parentKey,
                'treeManageHash' => $newHash,
                'treeRemoveHash' => ArrayHelper::getValue($data, 'treeRemoveHash', ''),
                'treeMoveHash' => ArrayHelper::getValue($data, 'treeMoveHash', ''),
            ] + $out;
        if (!empty($data['nodeViewParams'])) {
            $params = ArrayHelper::merge($params, unserialize($data['nodeViewParams']));
        }
        if (!empty($module->unsetAjaxBundles)) {
            $cb = function ($e) use ($module) {
                foreach ($module->unsetAjaxBundles as $bundle) {
                    unset($e->sender->assetBundles[$bundle]);
                }
            };
            Event::on(View::class, View::EVENT_AFTER_RENDER, $cb);
        }
        TreeSecurity::checkSignature('manage', $oldHash, $newHash);
        return $this->renderAjax($out['nodeView'], ['params' => $params]);
    };
    return self::process(
        $callback,
        Yii::t('kvtree', 'Error while viewing the {node}. Please try again later.', $nodeTitles),
        null
    );
    }
    

我怎样才能实现它?任何帮助将不胜感激。

标签: treeviewyii2-advanced-apptreenodekartik-v

解决方案


实现隐藏/显示某些节点​​的一种方法可能如下:

  • 在视图中你应该有你的数据库表名。

  • 查找您感兴趣的表名。

  • 在表名的文件夹内应该有类似的文件名:_form.php、_script.php 和 index.php

  • index.php 文件应该有一些用途,其中应该有: ...

    使用kartik\tree\TreeView;

    使用kartik\tree\Module;

...

  • 在这些 use 语句之后,您可以添加以下代码:

    /** @var 整数 $uid */

      // get current logged in user id.
    
      // this is used to control showing tree content, and
    
      // to control form fields.
    
      if (isset(Yii::$app->user)) {
          $uid = Yii::$app->user->getId();
      }
    
  • 所以现在登录的用户 id 保存在变量 $uid 中

  • 在同一个 index.php 文件中,您应该有呈现树视图的代码。开头是:echo TreeView::widget

  • 在此 TreeView::widget([.. 中,您可以添加一个查询,该查询仅呈现当前登录的用户内容,如下所示:

    'query' => YourTableName::find()->where(['user_id' => $uid])->addOrderBy('root, lft'),

... 其他设置 ...

如果您希望管理员查看或更改内容,您可以添加一个控制器,例如名为 AdminController,然后在这个 index.php TreeView::widget 中您可以添加更多选项,如下所示:

echo TreeView::widget([

    'query' => YourTableName::find()->where(['user_id' => $uid])->addOrderBy('root, lft'),

    'headingOptions' => ['label' => 'YourLableName'],

    //'rootOptions' => ['label' => '<span class="text-success">Root</span>'],

    'fontAwesome' => false,

    'isAdmin' => true,

    'showInactive' => AdminController::isAdmin(),

    'displayValue' => 0,

    'showIDAttribute' => true,

    'emptyNodeMsg' => ' type some msg here ... .',

    'showCheckbox' => false,

    'multiple' => false,

    'options' => ['id' => 'treeID'],

    'allowNewRoots' => false,

    'toolbar' => [
    'create' => ['alwaysDisabled' => true],
    //'remove' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-up' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-down' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-left' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    // 'move-right' => ['alwaysDisabled' => !(AdminController::isAdmin())],
    //'remove' => false,
    ],

    'cascadeSelectChildren' => false,

    //'softDelete' => false,

    'iconEditSettings'=> [
    'show'      => 'list',
    'listData'  => [
    // 'folder' => 'Folder',
    'file' => 'File',
    'star' => 'Star',
    'bell' => 'Bell',
    // 'phone' => 'Phone',
    ]
],

'cacheSettings' => ['enableCache' => true],

'nodeAddlViews' => [
    Module::VIEW_PART_1 => '@app/views/mappings/_form',
    ],
]);
  • 这只是一个小小的开始,但您可以更进一步。例如,假设用户未登录或假设您想以任何方式显示某些节点​​。在这些情况下,您可以使用 switch case 语句并检查例如 $uid 是否未定义(未设置,因为用户未登录)在这种情况下,您可以要求用户登录或呈现或显示不同的树视图:

    switch ($SomeVariable) { case "case_to_check": echo TreeView::widget([ ... 'query' => TableName::find()->where(['user_id' => $uid])->addOrderBy( 'root, lft'), ... break;
    case "another_case": echo TreeView::widget([ ... break; 默认值: echo TreeView::widget([ ...

== 您也可以在 index.php 的顶部添加 html select,如下所示:

<select name="Give_any_name_you_like" size=1 class="btn btn-primary" style="margin-bottom: 0.5em; margin-left: 0.5em; ">
<option value="0">Select Node</option>
<option value="1">mynodes</option>
<option value="2">othernodes</option>
<option value="3">allnodes</option>
</select>

然后使用java脚本过滤和捕获选定的值,然后你可以在switch case中使用这个vale来显示某些节点​​。您可以将 java 脚本代码放在 <?php 块中,在 switch case 或 echo TreeView::widget([ 之前。java 脚本代码可能如下所示:

$this->registerJs("
$('select[name=" . "The_name_you_give_in_select" . "]').change(function(){     
var value = $(this).val();                    
switch(value) {
case '1':
window.location.href = \"your-page-name?what=mynodes\" ; 
break;
case '2':
window.location.href = \"your-page-name?what=othernodes\" ;
break;        
default:
window.location.href = \"your-page-name?what=allnodes\" ;
}   

});", View::POS_READY); 

=== 然后你检查什么在 switch case 中的值并使用它来过滤要显示的树节点。类似这段代码的代码就在 java 脚本代码上方:

/** @var integer $The_name_you_give_in_select */
// get value from selection menu.
// this is used to filter and show desired tree.
if (isset($_GET['what'])) {
$The_name_you_give_in_select = $_GET['what'];
} else {
$The_name_you_give_in_select = "defaultcase";
}     
// Then in switch case:     
switch ($The_name_you_give_in_select) {
case "mynodes":
echo TreeView::widget([
...
break;
Case "othernodes":
echo TreeView::widget([
...
break;
default:
echo TreeView::widget([
...

============= === 你也可能想在views/your_table_name/_form.php中做一些改变

  • 在 _form.php 中,您还可以控制要显示的字段,使哪些字段可编辑或只读等,如下所示: == _form.php:

    ... /** @var 整数 $userid */

      // save current node user id in var $userid
    
      // to be used to control form fields
    
      $userid = $node->user_id;
    
      ...
    
      if(isset($userid)){
      $username = Yii::$app->user->identity;
      }
    
      ...
    
      <div class="your-form">
      ...
      <?= $form->field($node, 'annotation')->textarea(['rows' => 6, 'readonly' => !(Yii::$app->user->identity->id == $userid or AdminController::isAdmin())]) ?>
    
      <?= $form->field($node, 'comments')->textarea(['rows' => 6, 'readonly' => !(Yii::$app->user->identity->id == $userid or AdminController::isAdmin())]) ?>
    
      <!--   <?/*= $form->field($username, 'username')->textInput(['maxlength' => true, 'readonly'=>true])->label('Created by User') */?>-->
    
      <?= $form->field($node, 'user_id')->textInput(['readonly'=>true]) ?>
    
      <?= $form->field($node, 'date_added')->textInput(['placeholder' => 'Date Added', 'readonly'=>true]) ?>
    
      </div>
    

========= === AdminContoler.php 可能看起来像这样:

<?php
namespace app\controllers;
use Yii;
...
class AdminController extends Controller
{

/**
*
* manage admins.
* add admins here
* this will allow admins more control on all tables, but not accessing and managing users
* controlling, accessing and managing users is configured through:
* - config/web.php and views/layouts/main.php
*  - (1) in config/web.php go to modules -> user -> admins and add username(s)that you want to be admin accessing and managing users
*  - (2) THEN in view views/layouts/main.php, follow the same logic in line 62 and add username(s).
*
* @return bool
*/
public static function isAdmin()
{
if (
Yii::$app->user->identity->username == 'type user name here'
or
Yii::$app->user->identity->username == 'type user name here'

// add more here for example by uncommenting the following lines and typing username that you want to be admin

// or
// Yii::$app->user->identity->username == 'type user name here'

// or
// Yii::$app->user->identity->username == 'type user name here'

// or
// Yii::$app->user->identity->username == 'type user name here'
) {
return true;
} else {
return false;
}
}
}

推荐阅读