3

(注:此为yii2高级应用)
需求:在布局中如何动态读取数据表中数据?并且具有全局性(即数据在全站都可有效)?
如上:除了使用session外,还有一种比较好的方式就是使用小部件。

带着问题进入事例:

在创建一个项目的后台,我把菜单导航栏写进数据表,所有菜单导航栏是通过数据表来控制的。那么,在布局中如何把菜单读出来呢?如下图
图片描述

如果使用控制器来渲染,菜单栏是不具有全局性。
这时,不部件是一个好的方案!不仅解决了读取数据表中的数据,还保证了菜单栏的全局性。

一、创建数据表 nav(菜单),并使用gii创建model

此表用来保存所有菜单数据。此步很简单,在此略过!
每个人的方式不一样,此例主要是讲解如何使用小物件。

二、创建小部件

在backend下创建components/NavWidget.php (高级应用后台是没有components的)


<?php
namespace backend\components;
use backend\models\Nav;
use yii\base\Widget;
use yii\helpers\Html;

class NavWidget extends Widget
{
    public function run()
    {
        //从数据表中读出数据
        $nav = Nav::find()
        ->where(['status' => 1])
        ->orderBy('sort ASC')
        ->all();
        foreach($nav as $_v){
            $navs[] = $_v->id.'|'.$_v->nav_cn.'|'.$_v->nav_en;
        }
        // 渲染视图
         return $this->render('@app/views/site/_nav', [
             'nav'=>$navs,
         ]);
    }
}

?>
  • run()方法是处理和返回数据表中的数据;

  • 这里是return了一个_nav.php的视图文件(具体地址是在backend/views/site/_nav.php),
    因为小部件需要渲染很多复杂内容,一种更好的办法是将内容放入这个视图文件里面。
    如果内容很少就直接return $nav;

  • 如果render不指定一个具体的地址会默认在backend/components/views/xxx.php;

让我们看一眼这个小部件渲染的视图文件 如下:

use yii\helpers\Html;
/* @var $this yii\web\View */
use yii\bootstrap\Nav;

   NavBar::begin([
        'brandLabel' => '首页',
        'brandUrl' => Yii::$app->homeUrl,
        'options' => [
            'class' => 'navbar-inverse navbar-fixed-top',
            'id' => 'menu-top',
        ],
        //'brandOptions' => ['class' => 'fa fa-flag fa-2x pull-left'],

    ]);

    if (Yii::$app->user->isGuest) {
        $menuItems[] = ['label' => '登陆', 'url' => ['/site/login']];
    } else {
//循环出菜单栏
        if(isset($nav)){
            for($n=0;$n<count($nav);$n++){
                $_v = explode('|',$nav[$n]);    
                $menuItems[] = [
                    'label' => $_v[1],
                    'url' => ["/$_v[2]/default/index",'id'=>$_v[0],'en'=>$_v[2]],
                    //'linkOptions' => ['class' => 'active'],
                    //'options' => ["id"=>"_M$n"],
                ];

            }
        }
        $menuItems[] = [
            'label' => ' Log out',
            'url' => ['/site/logout'],
            'linkOptions' => ['data-method' => 'post','class'=>'fa fa-sign-out'],
        ];

    }
    echo Nav::widget([
        'options' => ['class' => 'navbar-nav navbar-right'],
        'items' => $menuItems,

    ]);
NavBar::end();

三、创建布局文件并使用刚创建的小部件

backend/views/layouts/main.php
//使用小部件

<?= NavWidget::widget() ?>

这样,小部件里面的动态数据就出来了,并且全局可使用。

另外:你如果想把NavWidget小部件里面有些参数通过get传到NewWidget这个小部件里面去(反正我是有这个需求的),可通过下面这种方式
在NavWidget渲染的视图里面(这段在上面有) 传个ID给别的小部件里面使用

'url' => ["/$_v[2]/default/index",'id'=>$_v[0]],

别的小部件使用处接收下

$id = isset($_GET['id']) ? $_GET['id'] : 1;
NewWidget::widget(['id'=>$id]) 

在NewWidget小部件里(部分代码)接收id

namespace backend\components;
use yii\base\Widget;
use yii\helpers\Html;

class NewWidget extends Widget
{
    public $id; //调用处把这个id传进来了
    public function run()
    {
        if(isset($this->id)){
            $navbar = xxx::find()
            ->with('xxx')  //联表
            ->where(['status' => 1,'nid'=>$this->id])//id就这样被使用了
            ->orderBy('id asc')
            ->all();
        }else{
            $navbar = '';
        }
       //......
    }
}

路飞
397 声望34 粉丝

引用和评论

0 条评论