我正在开始使用JSF 2作为视图技术的新Web应用程序.我之前没有使用过JSF的经验,对这些概念有点困惑.
我阅读了一些关于JSF的文档,其主要思想是它是一个基于组件的框架.应用程序是从组件构建的.
但是现在有两种创建组件的方法,正如我所理解的:
1.组合 - 可以包含在页面中的组件集合
2. composite - 一个新的组件,它封装了一些组件并向用户公开了一个接口
选择它们的基本规则是什么?
例如,我想向用户显示产品列表.对于这个列表,我应该创建我自己的组件,我将其添加到主布局,以分隔视图代码.那么这个列表应该是一个组合还是复合?
我希望有人可以帮助我清理这些基本的东西.
提前致谢,
在我看来,复合组件的属性不允许泛型类型.这是一个简单的测试用例:
<cc:attribute name="stringList" type="java.util.List<java.lang.String>" />
Run Code Online (Sandbox Code Playgroud)
我得到的错误是,
java.lang.ClassNotFoundException: java.util.List<java.lang.String>
Run Code Online (Sandbox Code Playgroud)
(如果我用<和>替换<和>,我会收到错误,因为它不是有效的XHTML.)
我知道该类型的通用部分将在运行时被删除,但我希望在这里使用泛型只是为了清楚地阅读代码.那可能吗?
我正在编写一个复合组件,你有一个名为的特殊标签:
<composite:insertChildren />
Run Code Online (Sandbox Code Playgroud)
其中插入了所有组件的子项.有没有办法知道该组件是否有孩子?就像一个可以在"呈现"属性上进行的布尔值.
我有一个递归的对象bean结构,就像
Master DTO列表 - >值 - > Master DTO列表
我正在尝试创建一个递归复合组件,其中包含一个输入文本和一个值绑定到值字段的按钮.我正在调用相同的组件来构建子类型,但它给了我堆栈溢出错误.
我尝试使用包含面板中的呈现属性,基于列表是否为空但不起作用.我试图在c:中包含对复合组件(来自复合组件内)的调用,但它不起作用.
我总是得到一个StackOverflowError.
有关如何构建递归复合组件的任何帮助都会有所帮助.谢谢你的时间!
如果我faces-config.xml使用JSF 2.0.4,我应该注册自定义验证器吗?我的自定义验证器使用Validator接口javax.faces.validator.Validator.
<cc:myComp id="customcomp1" ... />
<cc:myComp id="customcomp2" ...>
<f:validator id="myvalidator" for="myComp" />
</cc:myComp>
Run Code Online (Sandbox Code Playgroud)
myComp.xhtml
<cc:interface>
<cc:attribute ... />
<!-- more attributes -->
</cc:interface>
<cc:implementation>
<h:panelGroup layout="block">
<h:inputText id="firstName" ... />
<h:inputText id="middleName" ... />
<h:inputText id="lastName" ... />
</h:panelGroup>
</cc:implementation>
Run Code Online (Sandbox Code Playgroud) <ui:composition xmlns="http://www.w3.org/1999/xhtml"
...
template="inputLayout.xhtml">
<composite:interface>
<composite:attribute name="name" />
<composite:attribute name="value" />
</composite:interface>
<composite:implementation>
<!-- <ui:define name="content"> -->
<h:message for="textPanel" style="color:red;" />
#{cc.attrs.name} :
<h:inputText id="name" value="#{cc.attrs.value}" />
<!-- <ui:define> -->
</composite:implementation>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
问题是即使是ui:define也会对内容进行评论.所以它就像ui:define被忽略或者我错过了什么?谢谢.
不幸的是,如果你试图动态创建标签,那么primefaces accordionPanel在版本2.2.1中效果不佳.这是我的情况,我需要在用户点击添加图标时创建手风琴,如果他点击x图标则删除.没问题,我已经创建了自己的复合组件,就像你在这里看到的那样:
<c:interface>
<c:attribute name="titulo" default="" required="false" />
<c:attribute name="renderizar" default="true" required="false" />
<c:attribute name="width" required="false" default="300"/>
<c:facet name="extra" required="false" />
</c:interface>
<c:implementation>
<h:outputStylesheet library="css" name="hrgiAccordion.css" target="head" />
<h:outputStylesheet library="css" name="clearfix.css" target="head" />
<h:outputScript library="js" name="hrgiAccordion.js" target="head" />
<h:panelGroup layout="block" rendered="#{cc.attrs.renderizar}"
styleClass="hrgi-accordion clearfix" style="width: #{cc.attrs.width}px;">
<div class="hrgi-cabecalho-accordion clearfix"
onclick="abrirAccordion(this)">
<h:outputLabel value="#{cc.attrs.titulo}" />
<c:renderFacet name="extra" required="false"/>
</div>
<h:panelGroup layout="block" class="hrgi-conteudo-accordion clearfix">
<c:insertChildren />
</h:panelGroup>
</h:panelGroup>
</c:implementation>
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我有一些具体的需求...手风琴选项卡的内容是一些选择和一个带有inputField和一个微调器(由我再次创建)的动态表,你可以在这里看到用户界面:

当用户在微调器中插入值时,标签"Total das parcelas"应该更新,但只有当对话框只有一个折叠式选项卡时它才会更新!看看生成的HTML代码,我看到不同手风琴标签中的微调器是相等的!可能这就是我无法更新值的原因.以下是此对话框的代码:
<ui:composition template="../templates/popupSubmit.xhtml">
<ui:param name="titulo" value="#{vendaMsg['popup.forma_pagamento.titulo']}"/>
<ui:param name="popup" value="#{modeloPopupFormaPagamento}"/>
<ui:param name="controladorPopup" value="#{controladorPopupFormaPagamento}"/> …Run Code Online (Sandbox Code Playgroud) 我想构建一个自定义的JSF组件.现在我从oracle上读了一些文档,看了几个代码示例.问题是我有点困惑:
似乎有两种方法可以使用JSF 2.0+构建自定义组件.据我所知,自JSF 2.0以来我可以使用这些复合组件来构建我自己的组件.
但与"经典"组件相比,它们有任何缺点吗?
当我使用Compisite Components时,我的组件会相当复杂吗?
例如,我的Component将在java中有一些工作,这可能与Composite Components有关吗?
在给定的情况下,我想将Facelet与不同的ManagedBeans一起使用,因此About操作bean作为参数给出:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" >
<h:body>
<ui:include src="ratings.xhtml" >
<ui:param name="createAction" value="#{myOneCreateAction}" />
<ui:param name="ratings" value="#{context.ratings}" />
</ui:include>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
我给create动作作为参数value="#{myOneCreateAction}"。
在该构面中,一个组件也在其他页面上多次使用-因此,我尝试在复合组件中对其进行重构。
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:io="http://java.sun.com/jsf/composite/inoutComponents">
<ui:composition>
<rich:dataTable id="ratingTblId"
value="#{ratings}"
var="rating">
<rich:column>
<io:removeButton
id="removeButton"
actionMethod="#{createAction.removeRating}"
immediate="true"
render=":#{rich:clientId('ratingTblId')}" />
<h:commandButton
id="removeButton2"
actionListener="#{createAction.removeRating}"
immediate="true" >
<f:ajax render="ratingTblId" />
</h:commandButton>
</rich:column>
</rich:dataTable>
</ui:composition>
</html>
Run Code Online (Sandbox Code Playgroud)
参见,如何actionMethod="#{createAction.removeRating}"针对组件给出方法。该组件本身如下所示:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:cc="http://java.sun.com/jsf/composite">
<!-- INTERFACE --> …Run Code Online (Sandbox Code Playgroud) 我在我的公司"继承"了一个JSF 2(JSF 2.2.7)应用程序并面临java.lang.IllegalStateException,因为两个组件似乎具有相同的ID.
视图的结构如下(为了说明目的,我提取了相关代码,它可能包含一些拼写错误/无效语法,因为我更改了一些名称):
<p:commandButton id="editButton"
action="#{controller.prepareItem()}"
update=":itemEditDlg" oncomplete="PF('itemtEditDlg').show()" />
<comp:editItemDlg id="itemEditDlg" />
<p:dialog id="anotherDlg" >
<h:form id="anotherForm">
<c:forEach items="#{controller.allArgs}" var="arg" >
<!-- next line is the problem -->
<comp:mycomponent arg="#{arg}" />
</c:forEach>
</h:form>
</p:dialog>
Run Code Online (Sandbox Code Playgroud)
mycomponent.xhtml如下所示:
<cc:interface>
<cc:attribute name="arg" required="true" />
</cc:interface>
<cc:implementation>
<p:inputText id="argValue" value="#{cc.attrs.arg}" />
<p:message id="argValueMessage" for="argValue" />
</cc:implementation>
Run Code Online (Sandbox Code Playgroud)
重要:mycomponent组件也在editItemDlg中使用(与"anotherDlg"中的方式相同),即在对话框和forEach循环中)
如果我点击editButton,我得到:
java.lang.IllegalArgumentException: Component ID anotherForm:j_idt192:argValue
has already been found in the view.
Run Code Online (Sandbox Code Playgroud)
它相当奇怪,因为"anotherDlg"在这种情况下并不是开放的,但显然已经渲染了.
我在StackTrace中获得以下信息(仅显示相关部分):
+id: j_idt192
type: javax.faces.component.UINamingContainer@399bd0dc
+id: j_id2
type: javax.faces.component.UIPanel@24ad3910
+id: argValue <===============
type: org.primefaces.component.inputtext.InputText@687d5c3f …Run Code Online (Sandbox Code Playgroud)