如何在JSF中制作可重用的组件?

发布于 2024-11-03 16:34:23 字数 2216 浏览 0 评论 0原文

我想要一个与模型绑定的可重用的 ui 组件。

例如:

  1. 我有一个链接到另一个 selectonemenu (如部门 -> 子部门)的 selectonemenu
  2. 想要将其作为一个复合组件
  3. 这个复合组件将绑定到一个特定的 JSF Bean

我认为这个想法可行我只使用一个复合组件。

但是如果我使用多个相同类型的compositeComponent,这将不起作用,因为compositeComponent的JSF Bean将是相同的(在本例中,我使用视图范围),并且将共享一个或多个复合组件之间的状态。

这是一个粗略的例子,说明了我的困惑。在本例中,Page1.xhtml(具有 Page1Bean.java 的主模型)使用 2 个 compositeComponents(由 MyCompositeComponent.java 的 JSF Bean 处理)。

复合组件将类似于:

<!-- one composite component that has 2 chained selectOneMenus -->
<h:selectOneMenu
    ...
    value="#{myCompositeComponentBean.firstComboValue}"
    valueChangeListener="#{myCompositeComponentBean.yyy}">
    <f:ajax event="valueChange" execute="@this" ... />
    <f:selectItem itemLabel="Choose one .." noSelectionOption="true" />
    <f:selectItems value="#{myCompositeComponentBean.firstComboList}" .... />
</h:selectOneMenu>
<h:selectOneMenu
    ...
    value="#{myCompositeComponentBean.secondComboValue}"
    valueChangeListener="#{myCompositeComponentBean.bbb}">
    <f:selectItem itemLabel="Choose one .." noSelectionOption="true" />
    <f:selectItems value="#{myCompositeComponentBean.secondComboList}" .... />
</h:selectOneMenu>

以及复合组件的 JSF Bean将会是这样的:

// this model will serve the composite component
@Named
@Scope("view")
public class MyCompositeComponentBean {
    private String firstComboValue, secondComboValue;
    private List<String> firstComboList, secondComboList;
    ...
}

这是 Page1.xhtml 的一个示例:

....
main department : <my:comboChainComponent /> <!-- 2 select items will be rendered here -->
secondary department : <my:comboChainComponent /> <!-- another 2 select items will be rendered here -->
....

以及 Page1Bean(Page1.xhtml 的 Main JSF Bean)

@Named
@Scope("view")
public class Page1Bean {
    // inject the first bean for the composite component 1
    @Inject private MyCompositeComponentBean bean1;
    @Inject private MyCompositeComponentBean bean2;
    ...
}

是否可以实现这种可重用性?

谢谢。

I would like to have a reusable ui component which is tied to the model.

For example :

  1. I have a selectonemenu that is chained to another selectonemenu (like department -> sub-department)
  2. Would like to make this a composite component
  3. This composite component is going to be tied to a specific JSF Bean

I think this idea works if im only using one compositeComponent.

But this will not work if i make use of more than one compositeComponent of the same type, since the compositeComponent's JSF Bean will be the same (in this example, im using view scope), and will share the state between one or more compositeComponents.

This is one rough example that illustrates my confusion. In this case, Page1.xhtml (with the main model of Page1Bean.java), makes use of 2 compositeComponents (which is handled by the JSF Bean of MyCompositeComponent.java)

The composite component will be something like :

<!-- one composite component that has 2 chained selectOneMenus -->
<h:selectOneMenu
    ...
    value="#{myCompositeComponentBean.firstComboValue}"
    valueChangeListener="#{myCompositeComponentBean.yyy}">
    <f:ajax event="valueChange" execute="@this" ... />
    <f:selectItem itemLabel="Choose one .." noSelectionOption="true" />
    <f:selectItems value="#{myCompositeComponentBean.firstComboList}" .... />
</h:selectOneMenu>
<h:selectOneMenu
    ...
    value="#{myCompositeComponentBean.secondComboValue}"
    valueChangeListener="#{myCompositeComponentBean.bbb}">
    <f:selectItem itemLabel="Choose one .." noSelectionOption="true" />
    <f:selectItems value="#{myCompositeComponentBean.secondComboList}" .... />
</h:selectOneMenu>

And the composite component's JSF Bean will be like :

// this model will serve the composite component
@Named
@Scope("view")
public class MyCompositeComponentBean {
    private String firstComboValue, secondComboValue;
    private List<String> firstComboList, secondComboList;
    ...
}

This is an example of Page1.xhtml :

....
main department : <my:comboChainComponent /> <!-- 2 select items will be rendered here -->
secondary department : <my:comboChainComponent /> <!-- another 2 select items will be rendered here -->
....

And the Page1Bean (Main JSF Bean for Page1.xhtml)

@Named
@Scope("view")
public class Page1Bean {
    // inject the first bean for the composite component 1
    @Inject private MyCompositeComponentBean bean1;
    @Inject private MyCompositeComponentBean bean2;
    ...
}

Is it possible to achieve this kind of reusability?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

貪欢 2024-11-10 16:34:23

为什么不采用这种方法呢。

<mytag:combo id="combo1" 
         value="#{bean.firstData}" 
         model="#{globalBean.getList()}"
         update="form1:combo2"   />

<mytag:combo id="combo2" 
         value="#{bean.secondData}" 
         model="#{globalBean.getSubList(bean.firstData)}"  />

您可以使用复合属性。

...
<composite:interface name="combo">
   ... define your attributes here
</composite:interface>

<composite:implementation>
<p:outputPanel id="content">
    <p:selectOneMenu id="select_menu_1" value="#{cc.attrs.value}">
         <f:selectItems value="#{cc.attrs.model}" />
        <p:ajax event="change" process="@this" update="#{cc.attrs.update}" />
    //add converter if you want 
    </p:selectOneMenu>
</p:outputPanel>
</composite:implementation>

Why don't use this kind of approach.

<mytag:combo id="combo1" 
         value="#{bean.firstData}" 
         model="#{globalBean.getList()}"
         update="form1:combo2"   />

<mytag:combo id="combo2" 
         value="#{bean.secondData}" 
         model="#{globalBean.getSubList(bean.firstData)}"  />

You can use composite attribute.

...
<composite:interface name="combo">
   ... define your attributes here
</composite:interface>

<composite:implementation>
<p:outputPanel id="content">
    <p:selectOneMenu id="select_menu_1" value="#{cc.attrs.value}">
         <f:selectItems value="#{cc.attrs.model}" />
        <p:ajax event="change" process="@this" update="#{cc.attrs.update}" />
    //add converter if you want 
    </p:selectOneMenu>
</p:outputPanel>
</composite:implementation>
最佳男配角 2024-11-10 16:34:23

根据您想要实现的内容,您可以使用一些“支持组件”(=与您的 Facelet 复合组件关联的 Java 类)。请参阅这篇文章: http://weblogs .java.net/blog/cayhorstmann/archive/2010/01/30/composite-input-components-jsf

也许,根据你真正在做什么,你可能可以更好地定义你的复合组件,主要使用更多参数和更好的传递值模型(如果需要)。我对您的应用程序缺乏一些了解,无法提供更好的建议。

Depending on what you are trying to implement, you could use some "backing component" (=a java class associated to your facelet composite component). See this post: http://weblogs.java.net/blog/cayhorstmann/archive/2010/01/30/composite-input-components-jsf

Still maybe, depending on what your are really doing, you could probably better define your composite components, mainly using more parameters and a better model for passing values (if needed). I'm lacking some knowledge of your app to give a better advice.

思念满溢 2024-11-10 16:34:23

在 JSF 2.0 中,创建复合组件轻而易举。
这是一个很好的教程:
http://weblogs.java.net/blog/driscoll/archive /2008/11/writing_a_simpl.html

In JSF 2.0, creating composite components is a snap.
Here is a good tutorial:
http://weblogs.java.net/blog/driscoll/archive/2008/11/writing_a_simpl.html

也只是曾经 2024-11-10 16:34:23

不确定我完全理解你,但你可能想将参数传递给你构建的 componentComposition。

    main department : <my:comboChainComponent worksOn="#{page1Bean.bean1}" /> <!-- 2 select items will be rendered here -->
secondary department : <my:comboChainComponent worksOn="#{page1Bean.bean2}"/> <!-- another 2 select items will be rendered here -->

希望它有帮助...

Not sure I understand you perfectly, but you might want to pass an argument to the componentComposition you build.

    main department : <my:comboChainComponent worksOn="#{page1Bean.bean1}" /> <!-- 2 select items will be rendered here -->
secondary department : <my:comboChainComponent worksOn="#{page1Bean.bean2}"/> <!-- another 2 select items will be rendered here -->

Hope it helps...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文