为Yii bootstrap当中的TbDropDown 添加html属性

1、TbDropDown是啥


上张图一看就明白了:

这是bootstrap提供的组件之一,在Yii bootstrap的插件当中对应于TbDropDown这个类。


2、为什么会遇到这个问题?


找到官方文档,我们可能习惯性的把代码抄下来了,如下:

        array(
            'class' => 'bootstrap.widgets.TbMenu',
            'htmlOptions' => array('class' => 'pull-right'),
            'items' => array(
                array('label' => Yii::app()->user->name, 'url' => '#',
                    'items' => array(
                        array('label' => 'Login', 'url' => 'javascript:void(0);', 'visible' => Yii::app()->user->isGuest),
                        array('label' => 'Register', 'url' => 'javascript:createUser();','visible' => Yii::app()->user->isGuest),
                        array('label' => 'Logout (' . Yii::app()->user->name . ')',  'url' => array('/site/logout'), 'visible' => !Yii::app()->user->isGuest),
                    )),
            ),
        ),

可以参考: http://www.cniska.net/yii-bootstrap/#tbMenu

没有看到DropDown?哈哈,因为它潜伏在TbMenu当中的,一个TbMenu其实就是上图当中的Guest这个item,而所谓的DropDown其实就是下面的Login和Register。不信看源码:(bootstrap/widget/TbMenuBase.php line 96)

if (isset($item['items']) && !empty($item['items']))
{
	$this->controller->widget('bootstrap.widgets.TbDropdown', array(
		'encodeLabel'=>$this->encodeLabel,
		'htmlOptions'=>isset($item['submenuOptions']) ? $item['submenuOptions'] : $this->submenuHtmlOptions,
		'items'=>$item['items'],
	));
}


好的,弄清楚是什么的时候,就该为什么了。我们看到在创建TbMenu的时候,里面的item的参数只有一个'url,而这个参数实际上对应于最终生成的<a href=""></a>里的href属性-----哇,万一我想要让这个标签执行一段js脚本怎么办?

有人说那你就让url="javascrip:js_method()"不就完了。我想虽然不是很推荐这种做法,但总比不能实现强。后来执行了一段代码,这段代码有返回值,最初在搜狗浏览器上面运行毫无压力,然后蛋疼的事情终于发生在了ie和Firefox身上:浏览器直接跳转了,并把返回值给显示出来。

逃避总不是办法,还是想想怎么样弄个onclick属性上去才是正招。


3、解决之道

翻文档的事儿就别指望了,因为没有。只能看源码了。

bootstrap/widget/TbDropdown.php line 57:

		if (isset($item['url']))
			return CHtml::link($item['label'], $item['url'], $item['linkOptions']);
		else
			return $item['label'];
传了个linkOptions进去?!

CHtml::link:

	public static function link($text,$url='#',$htmlOptions=array())
	{
		if($url!=='')
			$htmlOptions['href']=self::normalizeUrl($url);
		self::clientChange('click',$htmlOptions);
		return self::tag('a',$htmlOptions,$text);
	}
咋变htmlOptions了?!

CHtml::tag

	public static function tag($tag,$htmlOptions=array(),$content=false,$closeTag=true)
	{
		$html='<' . $tag . self::renderAttributes($htmlOptions);
		if($content===false)
			return $closeTag && self::$closeSingleTags ? $html.' />' : $html.'>';
		else
			return $closeTag ? $html.'>'.$content.'</'.$tag.'>' : $html.'>'.$content;
	}

renderAttributes函数的核心代码:

		foreach($htmlOptions as $name=>$value)
		{
			if(isset($specialAttributes[$name]))
			{
				if($value)
				{
					$html .= ' ' . $name;
					if(self::$renderSpecialAttributesValue)
						$html .= '="' . $name . '"';
				}
			}
			elseif($value!==null)
				$html .= ' ' . $name . '="' . ($raw ? $value : self::encode($value)) . '"';
		}
到这里,我们发现其实htmlOptions里面的键值对被原封不动的写入了html的a标签。


所以如果你想要在最后生成的a标签里面添加相应的属性,那么就在最开始的代码当中添加 'linkOptions'=>array(.....)

        array(
            'class' => 'bootstrap.widgets.TbMenu',
            'htmlOptions' => array('class' => 'pull-right'),
            'items' => array(
                array('label' => Yii::app()->user->name, 'url' => '#',
                    'items' => array(
                        array('label' => 'Login', 'url' => 'javascript:void(0);', 'linkOptions' => array('onclick' => 'createUser()'), 'visible' => Yii::app()->user->isGuest),
                        array('label' => 'Register', 'url' => 'javascript:createUser();','visible' => Yii::app()->user->isGuest),
                        array('label' => 'Logout (' . Yii::app()->user->name . ')',  'url' => array('/site/logout'), 'visible' => !Yii::app()->user->isGuest),
                    )),
            ),
        ),


4、总结


(1)yii bootstrap的插件当中,经常会用htmlOptions为标签设置html属性,但这次居然用了linkOPtions(中间有一次变身你们还记得不?)

(2)没事儿还是看看源码吧。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值