2

在我的 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;
    }
}

不过这看起来很难看,我不知道它是否会起作用。

4

3 回答 3

5

自从提出这个问题后,我发现了一个非常容易实现的明显解决方案。

作为 JSF 操作目标的方法必须不接受任何参数并返回一个字符串。事实证明,String 类已经有一个匹配这个签名的方法 - toString()

因此,我已将 UI 循环更改为以下内容:

<ui:repeat value="#{fn:split(trail, ',')}" var="key">
    <h:commandLink action="#{key.toString}" ... /> 
</ui:repeat>

This allows the dynamically evaluated key to be the JSF action outcome, and doesn't require any additional classes or ugly hackery.

于 2009-12-13T23:13:22.257 回答
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>
于 2009-08-06T13:58:42.663 回答
1

为什么不创建一个以编程方式生成 h:commandLink 对象的自定义组件?这可能是“最干净”的解决方案。

于 2009-08-06T07:42:06.047 回答