1

我已经构建了一个引导菜单,现在我想用 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. 该小部件生成下拉链接,如<a class="dropdown-toggle" href="/main/#4" data-toggle="dropdown">dropdown menu <span class="caret"></span></a>如何摆脱data-toggle="dropdown"class="dropdown-toggle"
  2. 搜索表单包含在<a></a>标签中。这就是导航栏坏了的原因: 在此处输入图像描述 我怎样才能摆脱不必要的标签?
4

1 回答 1

1

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

\yii\bootstrap\begin()NavBar 的和 调用之间包含的任何内容\yii\bootstrap\end()都被视为导航栏的内容。您可以使用诸如yii\bootstrap\Nav\yii\widgets\Menu构建此类内容的小部件。

因此,只需在调用 .$items之后Nav::widget()和调用NavBar::end().

您可以使用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' => 'dropdown-toggle' ] );添加的行在那里上课,然后将namespace您调用的位置Nav更改yii\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);
    }

}
于 2018-08-12T21:04:19.247 回答