2

我可能没有正确思考 JSF 中的可视化组件,但我想这是我的问题的一部分。我的问题是围绕 JSF <ui:component> 实现中声明的变量似乎缺乏范围。

所以,假设我有 /resources/comp/myPanel.xhtml:

<?xml version="1.0" encoding="UTF-8" ?>
<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:f="http://java.sun.com/jsf/core" 
              xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:c="http://java.sun.com/jsp/jstl/core"      
              xmlns:cc="http://java.sun.com/jsf/composite">
    <cc:interface>
    </cc:interface>
    <cc:implementation>
        <f:loadBundle var="bundle" basename="panelOnly.bundle" />

        <h:outputText value="#{bundle.myText}" />
    </cc:implementation>
</ui:component>

并且有一个资源包被加载到该组件中,panelOnly/bundle.properties:

myText = This is a panel resource

然后我有一个放置 myPanel 组件 mainPage.xhtml 的页面:

<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:comp="http://java.sun.com/jsf/composite/comp">
    <h:body>
        <f:view>
            <f:loadBundle basename="mainPage.bundle" var="bundle" />

            <comp:myPanel />

            <h:outputText value="#{bundle.myText}" />
        </f:view>
    </h:body>
</html>

并且有一个资源包被加载到主页中,mainPage/bundle.properties:

myText = This is a main page resource

现在,我假设我的页面应该呈现为:

This is a panel resource
This is a main page resource

但是,相反,我得到:

This is a panel resource
This is a panel resource

我认为这是因为我破坏了组件中“bundle”符号所指的内容,因此当 mainPage.xhtml 尝试解析该值时,它会查看组件的“bundle”对象而不是原始 mainPage 的对象。

迄今为止,我的解决方法是在我的组件中使用唯一的命名变量,这些变量永远不会与我的主页上的变量发生冲突。但如果有一种方法可以让 JSF 将我的组件中声明的任何内容识别为本地范围的变量,而不是破坏调用者的符号,我会更愿意。

我认为还有其他标签可以用来在#{cc.attrs...} 下制作局部范围的变量。如果您可以在答案中列举我的本地范围选项,那将非常有帮助。我怀疑我的 <f:loadBundle> 是一种特殊情况,并且可能没有解决方法,因为它不是在设计时考虑到 <ui:component> 的。

谢谢!

PS 我正在运行 Mojarra 2.1.1 (FCS 20110408)

(针对格式化和复制粘贴错误进行了编辑,2011 年 6 月 15 日)

4

1 回答 1

3

不幸的是,这就是<f:loadBundle>工作原理。这是整个视图的一次性设置。并且同一视图中的任何后续<f:loadBundle>调用都将覆盖前一个。

你最好的办法是通过一个支持组件来管理它。

<cc:interface componentType="myPanel">

@FacesComponent(value="myPanel")
public class MyPanel extends UIComponentBase implements NamingContainer {

    private ResourceBundle bundle;

    public MyPanel() {
        bundle = ResourceBundle.getBundle("panelOnly.bundle", 
            FacesContext.getCurrentInstance().getViewRoot().getLocale());
    }

    @Override
    public String getFamily() {
        return "javax.faces.NamingContainer";
    }

    public ResourceBundle getBundle() {
        return bundle;
    }

}

可以用作

<cc:implementation>
    <h:outputText value="#{cc.bundle.myText}" />
</cc:implementation>
于 2011-06-15T18:00:37.357 回答