【问题标题】:Yii2 : Create custom menuYii2 : 创建自定义菜单
【发布时间】:2019-01-19 07:17:15
【问题描述】:

我已经构建了一个引导菜单,现在我想用 Yii2 Nav 小部件重现它。所以,这里是初始状态:

<nav class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="true">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">BrandLogo</a>
        </div>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1" aria-expanded="true">
            <ul class="nav navbar-nav">
                <li>
                    <a href="#1" class="current">simple menu</a>
                </li>
                <li class="dropdown">
                    <a href="#4">dropdown menu <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li>
                            <a href="#2">Submenu#1</a>
                        </li>
                        <li>
                            <a href="#3">Submenu#2</a>
                        </li>
                    </ul>
                </li>
            </ul>
            <form class="navbar-form navbar-left" action="/action_page.php">
                <div class="form-group has-feedback search">
                    <input type="text" class="form-control" placeholder="Search" />
                    <i class="glyphicon glyphicon-search form-control-feedback"></i>
                </div>
            </form>
        </div>
    </div>
</nav>

下面是它的样子:

现在我想用 Nav 小部件做同样的菜单。代码如下:

NavBar::begin([
    'brandLabel' => 'BrandLogo',
    'brandUrl' => Yii::$app->homeUrl,
    'options' => [
        'class' => 'navbar-inverse',
    ],
]);

$menuItems = [
    [
        'label' => 'simple menu',
        'url' => ['#1']
    ],
    [
        'label' => 'dropdown menu',
        'url' => ['#4'],
        'items' => [
            [
                'label' => 'Submenu#1',
                'url' => ['#1'],
            ],
            [
                'label' => 'Submenu#2',
                'url' => ['#2'],
            ],
        ]
    ],
    [
        'label' => '
            <form class="navbar-form navbar-left" action="/action_page.php">
                <div class="form-group has-feedback search">
                    <input type="text" class="form-control" placeholder="Search" />
                    <i class="glyphicon glyphicon-search form-control-feedback"></i>
                </div>
            </form>',
        'encode' => false,
        'url' => false,
    ],
];


if (count($menuItems)) {
    echo Nav::widget([
        'options' => ['class' => 'navbar-nav'],
        'items' => $menuItems,
    ]);
}

NavBar::end();

问题是结果不相等。我发现了一些问题:

  1. 小部件生成下拉链接为&lt;a class="dropdown-toggle" href="/main/#4" data-toggle="dropdown"&gt;dropdown menu &lt;span class="caret"&gt;&lt;/span&gt;&lt;/a&gt; 我怎样才能摆脱data-toggle="dropdown"class="dropdown-toggle"
  2. 搜索表单被包装到&lt;a&gt;&lt;/a&gt; 标记中。这就是导航栏坏了的原因: 我怎样才能摆脱不必要的标签?

【问题讨论】:

  • 你能添加实际工作的html 结构,你必须使用 Yii2 Nav 创建/转换导航
  • 它已经存在 - 第一个代码块名为“初始状态”。
  • 如果有人问我为什么要摆脱 data-toggledropdown-toggle 这里是 answer

标签: yii2 yii2-widget


【解决方案1】:

那是因为您没有遵循实际的 HTML 结构,因此您需要在 ul 之后而不是在 li 内添加表单,但该表单应该是 NavBar 的一部分,如果你看看定义

\yii\bootstrap\begin()\yii\bootstrap\end() NavBar 的调用被视为 导航栏。您可以使用诸如yii\bootstrap\Nav\yii\widgets\Menu 建立这样的内容。

所以只需在调用Nav::widget() 之后和调用NavBar::end() 之前将您的表单移到$items 之外。

您可以使用linkOptions 自定义或删除与链接相关的类或任何其他属性

<?php
NavBar::begin([
    'brandLabel' => 'BrandLogo',
    'brandUrl' => Yii::$app->homeUrl,
    'options' => [
        'class' => 'navbar-inverse',
    ],
]);

$menuItems = [
    [
        'label' => 'simple menu',
        'url' => ['#1']
    ],
    [
        'label' => 'dropdown menu',
        'url' => ['#4'],
        'linkOptions' => [
            'class' => 'my-class',
            'data' => [
                'toggle' => ''
            ]
        ],
        'items' => [
            [
                'label' => 'Submenu#1',
                'url' => ['#1'],
            ],
            [
                'label' => 'Submenu#2',
                'url' => ['#2'],
            ],
        ]
    ],
];


if( count($menuItems) ){
    echo Nav::widget([
        'options' => ['class' => 'navbar-nav'],
        'items' => $menuItems,
    ]);
}
?>
<form class="navbar-form navbar-left" action="/action_page.php">
    <div class="form-group has-feedback search">
        <input type="text" class="form-control" placeholder="Search" />
        <i class="glyphicon glyphicon-search form-control-feedback"></i>
    </div>
</form>
<?php
NavBar::end();

编辑

如果您希望完全删除类名dropdown-toggle,那么您可能必须通过扩展小部件来覆盖yii\bootstrap\Nav::renderItems(),因为它默认添加为引导类,因此您只需复制renderItems()到您的扩展类并注释掉在其中添加类的Html::addCssClass ( $linkOptions , [ 'widget' =&gt; 'dropdown-toggle' ] ); 行,然后将您调用Navnamespaceyii\bootstrap\Nav::widget() 更改为common\components\Nav::widget()

在您的common\components\ 中添加以下类,或者如果您打算将其复制到其他地方,请更新代码中的命名空间

<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace common\components;

use yii\bootstrap\Nav as BaseNav;
use yii\bootstrap\Html;
use yii\helpers\ArrayHelper;
use yii\base\InvalidConfigException;

class Nav extends BaseNav {

    /**
     * Renders a widget's item.
     * @param string|array $item the item to render.
     * @return string the rendering result.
     * @throws InvalidConfigException
     */
    public function renderItem($item) {
        if( is_string($item) ){
            return $item;
        }
        if( !isset($item['label']) ){
            throw new InvalidConfigException("The 'label' option is required.");
        }
        $encodeLabel = isset($item['encode']) ? $item['encode'] : $this->encodeLabels;
        $label = $encodeLabel ? Html::encode($item['label']) : $item['label'];
        $options = ArrayHelper::getValue($item, 'options', []);
        $items = ArrayHelper::getValue($item, 'items');
        $url = ArrayHelper::getValue($item, 'url', '#');
        $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);

        if( isset($item['active']) ){
            $active = ArrayHelper::remove($item, 'active', false);
        } else{
            $active = $this->isItemActive($item);
        }

        if( empty($items) ){
            $items = '';
        } else{
            $linkOptions['data-toggle'] = 'dropdown';
            Html::addCssClass($options, ['widget' => 'dropdown']);
//            Html::addCssClass ( $linkOptions , [ 'widget' => 'dropdown-toggle' ] );
            if( $this->dropDownCaret !== '' ){
                $label .= ' ' . $this->dropDownCaret;
            }
            if( is_array($items) ){
                $items = $this->isChildActive($items, $active);
                $items = $this->renderDropdown($items, $item);
            }
        }

        if( $active ){
            Html::addCssClass($options, 'active');
        }

        return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options);
    }

}

【讨论】:

  • 我的第二个问题完全解决了!谢谢你。不幸的是,我仍然在输出 html 中得到 dropdown-toggle 类。 &lt;a class="my-class dropdown-toggle" href="#4" data-toggle=""&gt;dropdown menu &lt;span class="caret"&gt;&lt;/span&gt;&lt;/a&gt;。现在我可以添加自己的类,但仍然无法删除现有的类。
  • 好吧,如果您希望从那里完全删除该类,您可能需要覆盖 yii\bootstrap\Nav::renderItems(),因为该类是由小部件添加的,我已经更新了答案,请参阅他编辑部分 @GHopper
猜你喜欢
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 2011-11-12
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多