在我的JSF / Facelets应用程序中,我想使用自定义标记从页面ID列表中动态生成痕迹痕迹:
<foo:breadcrumbs trail="foo,bar,baz"/>
这应该产生类似的东西:
<h:commandLink action="foo" ... />
<h:commandLink action="bar" ... />
<!-- (etc.) -->
我的代码看起来像这样:
<ui:repeat value="#{fn:split(trail, ',')}" var="key">
<h:commandLink action="#{key}" ... />
</ui:repeat>
此代码的问题是#{key}
被解释为方法绑定。但是,我只想将#{key}
的字符串值作为导航结果返回。我怎样才能做到这一点?
我唯一能想到的是创建一个具有outcome
字段和动作处理程序的虚拟托管bean,并像这样调用它:
<h:commandLink action="#{dummy.click}" ...>
<f:setPropertyActionListener target="#{dummy.outcome}" value="#{key}" />
</h:commandLink>
使用如此定义的虚拟类:
public class Dummy {
private String outcome;
public String click() {
return outcome;
}
public void setOutcome(String outcome) {
this.outcome = outcome;
}
public void getOutcome() {
return outcome;
}
}
虽然看起来很丑陋,但我不知道它是否有效。
答案 0 :(得分:5)
自从提出这个问题以来,我发现了一个非常简单易用的解决方案。
作为JSF操作目标的方法必须不接受任何参数并返回String。
事实证明,String类已经有一个匹配此签名的方法 - toString()
!
所以,我已将UI循环更改为以下内容:
<ui:repeat value="#{fn:split(trail, ',')}" var="key">
<h:commandLink action="#{key.toString}" ... />
</ui:repeat>
这允许动态评估的key
是JSF操作结果,并且不需要任何其他类或丑陋的hackery。
答案 1 :(得分:3)
有几种方式让人想起。
选项1
坚持使用commandLink并直接从动作绑定中的请求映射中读取var
:
public String click() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
Map<String, Object> reqMap = extContext.getRequestMap();
return (String) reqMap.get("uirepeatVar");
}
(转发器具有属性var="uirepeatVar"
。)
选项2
切换到outputLink并在服务器上构建GET链接:
public List<String> getViewUrls() {
List<String> views = Arrays.asList("/index.xhtml", "/idtable.xhtml");
List<String> urls = new ArrayList<String>();
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ViewHandler viewHandler = application.getViewHandler();
for (String view : views) {
String url = viewHandler.getActionURL(context, view);
urls.add(url);
}
return urls;
}
查看:
<ui:repeat value="#{breadcrumbBean.viewUrls}" var="url">
<h:outputLink value="#{url}">#{url}</h:outputLink> <br />
</ui:repeat>
答案 2 :(得分:1)
为什么不创建一个以编程方式生成h:commandLink对象的自定义组件?它可能是“最干净”的解决方案。