如何动态构建 Bootfaces <b:dropmenu>
How to build Bootfaces <b:dropmenu> dynamically
我的应用程序基于 JSF 2.2 和 Primefaces 6.2。我需要创建一个菜单栏,其中子菜单将显示在 "drop-up" 中,而不是下拉菜单中。我无法在 Primefaces 中实现这种下拉效果,不得不使用 Bootsfaces 的 <b:dropMenu>
组件,它为此提供了一个 "drop" 属性(drop="up" 创建了一个下拉) .更多信息:
https://showcase.bootsfaces.net/layout/navbars.jsf
使用 <b:dropMenu>
,它以这种方式呈现,对我来说看起来不错:
Screenshot。
但是,我需要通过 Java 代码动态构建 <b:dropMenu>
。
是否可以将某种模型属性与 <b:dropMenu>
一起使用,类似于 Primefaces 菜单所具有的属性?
在我当前的代码中,我以这种方式硬编码了子菜单,我想将其删除并动态构建:
<b:navBar inverse="true" fluid="true" >
<b:navbarLinks >
<b:dropMenu value="Vehicle Services" drop="up" >
<b:navLink value="Repairs" href="#"></b:navLink>
<b:navLink value="Sales" href="#"></b:navLink>
<b:navLink value="Financing" href="#"></b:navLink>
<b:navLink value="Insurance" href="#"></b:navLink>
<b:navLink value="Leasing" href="#"></b:navLink>
<b:navLink value="Driving School" href="#"></b:navLink>
<b:navLink value="Legal" href="#"></b:navLink>
</b:dropMenu>
.........
.........
.........
-- 编辑--
按照@Selaron 的代码示例,尝试从 XHTML 中的 <b:NavBarLinks>
动态构建:
<h:form>
<b:navBar inverse="true" fluid="true">
<b:navbarLinks>
<f:event listener="#{extranetController.initializeNavBarLinksChildren}" type="postAddToView" />
</b:navbarLinks>
</b:navBar>
</h:form>
豆中:
public void initializeNavBarLinksChildren(ComponentSystemEvent e) {
UIComponent component = e.getComponent();
//assert that its a NavBarLinks
DropMenu dropMenu = new DropMenu();
dropMenu.setDrop("up");
dropMenu.setValueExpression("value", Utility.createValueExpression("Vehicle Services", String.class));
NavLink navLink1 = new NavLink();
navLink1.setValue("Free Service");
navLink1.setHref("#");
dropMenu.getChildren().add(navLink1);
NavLink navLink2 = new NavLink();
navLink2.setValue("Paid Service");
navLink2.setHref("#");
dropMenu.getChildren().add(navLink2);
component.getChildren().add(dropMenu);
}
在我使用的 Utility.createValueExpression() 中...目的是将字符串设置为 valueExpression:
public static ValueExpression createValuExpression(String expression, Class clazz) {
FacesContext fc = FacesContext.getCurrentInstance();
ELContext elContext = fc.getELContext();
ExpressionFactory expFactory = fc.getApplication().getExpressionFactory();
ValueExpression ret = expFactory.createValueExpression(elContext, expression, clazz);
return ret;
}
遗憾的是,在 UI 上,只有 DropMenu 出现(即 "Vehicle Services"),但是 none 我在其下定义的两个 NavLink。我不太确定我做错了什么。我怀疑它是否与我为 DropMenu 设置 valueExpression 的方式有关(尽管值 "Vehicle Services" 确实与向上插入符号图标一起显示得很好。)
我没有找到允许以 PrimeFaces 方式指定动态菜单模型的属性,但这里有一个解决方法:
<h:form>
<b:navBar inverse="true" fluid="true">
<b:navbarLinks>
<b:dropMenu value="Vehicle Services" drop="up">
<f:event listener="#{myBean.initializeDropMenuChildren}"
type="postAddToView" />
</b:dropMenu>
</b:navbarLinks>
</b:navBar>
</h:form>
这会注册一个事件侦听器 (f:event
),一旦 b:dropMenu
添加到视图中就会触发一次。然后,您可以动态实例化并向该菜单添加链接:
package my.package;
import javax.faces.component.UIComponent;
import javax.faces.event.ComponentSystemEvent;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import net.bootsfaces.component.dropMenu.DropMenu;
import net.bootsfaces.component.navLink.NavLink;
@Named
@RequestScoped
public class MyBean {
public void initializeDropMenuChildren(ComponentSystemEvent e) {
UIComponent component = e.getComponent();
assert component instanceof DropMenu;
NavLink navLink = new NavLink();
navLink.setValue("wow");
navLink.setHref("#");
component.getChildren().add(navLink);
}
}
编辑:
响应您的编辑:看起来 b:navbarLinks
组件不喜欢在 xhtml 中完全为空。尝试将 f:event 直接添加到 b:navBar
中并从那里添加所有子项。或者将您的标记更改为:
<h:form>
<b:navBar>
<b:navbarLinks>
<b:dropMenu value="dummy" drop="down"/>
<f:event listener="#{myBean.initializeDropMenuChildren}"
type="postAddToView" />
</b:navbarLinks>
</b:navBar>
</h:form>
在添加 dropMenus
之前,执行 component.getChildren().clear();
删除虚拟 dropMenu
。
我的应用程序基于 JSF 2.2 和 Primefaces 6.2。我需要创建一个菜单栏,其中子菜单将显示在 "drop-up" 中,而不是下拉菜单中。我无法在 Primefaces 中实现这种下拉效果,不得不使用 Bootsfaces 的 <b:dropMenu>
组件,它为此提供了一个 "drop" 属性(drop="up" 创建了一个下拉) .更多信息:
https://showcase.bootsfaces.net/layout/navbars.jsf
使用 <b:dropMenu>
,它以这种方式呈现,对我来说看起来不错:
Screenshot。
但是,我需要通过 Java 代码动态构建 <b:dropMenu>
。
是否可以将某种模型属性与 <b:dropMenu>
一起使用,类似于 Primefaces 菜单所具有的属性?
在我当前的代码中,我以这种方式硬编码了子菜单,我想将其删除并动态构建:
<b:navBar inverse="true" fluid="true" >
<b:navbarLinks >
<b:dropMenu value="Vehicle Services" drop="up" >
<b:navLink value="Repairs" href="#"></b:navLink>
<b:navLink value="Sales" href="#"></b:navLink>
<b:navLink value="Financing" href="#"></b:navLink>
<b:navLink value="Insurance" href="#"></b:navLink>
<b:navLink value="Leasing" href="#"></b:navLink>
<b:navLink value="Driving School" href="#"></b:navLink>
<b:navLink value="Legal" href="#"></b:navLink>
</b:dropMenu>
.........
.........
.........
-- 编辑--
按照@Selaron 的代码示例,尝试从 XHTML 中的 <b:NavBarLinks>
动态构建:
<h:form>
<b:navBar inverse="true" fluid="true">
<b:navbarLinks>
<f:event listener="#{extranetController.initializeNavBarLinksChildren}" type="postAddToView" />
</b:navbarLinks>
</b:navBar>
</h:form>
豆中:
public void initializeNavBarLinksChildren(ComponentSystemEvent e) {
UIComponent component = e.getComponent();
//assert that its a NavBarLinks
DropMenu dropMenu = new DropMenu();
dropMenu.setDrop("up");
dropMenu.setValueExpression("value", Utility.createValueExpression("Vehicle Services", String.class));
NavLink navLink1 = new NavLink();
navLink1.setValue("Free Service");
navLink1.setHref("#");
dropMenu.getChildren().add(navLink1);
NavLink navLink2 = new NavLink();
navLink2.setValue("Paid Service");
navLink2.setHref("#");
dropMenu.getChildren().add(navLink2);
component.getChildren().add(dropMenu);
}
在我使用的 Utility.createValueExpression() 中...目的是将字符串设置为 valueExpression:
public static ValueExpression createValuExpression(String expression, Class clazz) {
FacesContext fc = FacesContext.getCurrentInstance();
ELContext elContext = fc.getELContext();
ExpressionFactory expFactory = fc.getApplication().getExpressionFactory();
ValueExpression ret = expFactory.createValueExpression(elContext, expression, clazz);
return ret;
}
遗憾的是,在 UI 上,只有 DropMenu 出现(即 "Vehicle Services"),但是 none 我在其下定义的两个 NavLink。我不太确定我做错了什么。我怀疑它是否与我为 DropMenu 设置 valueExpression 的方式有关(尽管值 "Vehicle Services" 确实与向上插入符号图标一起显示得很好。)
我没有找到允许以 PrimeFaces 方式指定动态菜单模型的属性,但这里有一个解决方法:
<h:form>
<b:navBar inverse="true" fluid="true">
<b:navbarLinks>
<b:dropMenu value="Vehicle Services" drop="up">
<f:event listener="#{myBean.initializeDropMenuChildren}"
type="postAddToView" />
</b:dropMenu>
</b:navbarLinks>
</b:navBar>
</h:form>
这会注册一个事件侦听器 (f:event
),一旦 b:dropMenu
添加到视图中就会触发一次。然后,您可以动态实例化并向该菜单添加链接:
package my.package;
import javax.faces.component.UIComponent;
import javax.faces.event.ComponentSystemEvent;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import net.bootsfaces.component.dropMenu.DropMenu;
import net.bootsfaces.component.navLink.NavLink;
@Named
@RequestScoped
public class MyBean {
public void initializeDropMenuChildren(ComponentSystemEvent e) {
UIComponent component = e.getComponent();
assert component instanceof DropMenu;
NavLink navLink = new NavLink();
navLink.setValue("wow");
navLink.setHref("#");
component.getChildren().add(navLink);
}
}
编辑:
响应您的编辑:看起来 b:navbarLinks
组件不喜欢在 xhtml 中完全为空。尝试将 f:event 直接添加到 b:navBar
中并从那里添加所有子项。或者将您的标记更改为:
<h:form>
<b:navBar>
<b:navbarLinks>
<b:dropMenu value="dummy" drop="down"/>
<f:event listener="#{myBean.initializeDropMenuChildren}"
type="postAddToView" />
</b:navbarLinks>
</b:navBar>
</h:form>
在添加 dropMenus
之前,执行 component.getChildren().clear();
删除虚拟 dropMenu
。