我只是不明白:如果我希望我的复合组件插入子项,我会使用 <composite:insertChildren/>
但在这种情况下#{cc.childCount}
总是返回0
.另一方面,如果我不使用 <composite:insertChildren/>
我总是在childCount
没有孩子被渲染的情况下得到正确的.为什么会这样?
我想在我的组件中做的就是在没有子节点时渲染一些"默认"面板,在其他情况下不渲染它 - 行为类似于<ui:insert name="param_name">default value</ui:insert>
.所以我需要insertChildren和childCount,它们似乎不能一起工作.
这是代码:
<my:test>
<h:outputText value="child1" rendered="#{some.trueValue}"/>
<h:outputText value="child2" rendered="#{some.trueValue}"/>
<my:test>
Run Code Online (Sandbox Code Playgroud)
如果我使用下面的实现,我会2
按预期呈现
<composite:implementation>
<h:outputText value="#{cc.childCount}"/>
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)
什么时候insertChildren
使用我得到两个孩子渲染,0
最后:
<composite:implementation>
<composite:insertChildren/>
<h:outputText value="#{cc.childCount}"/>
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)
而我的目标是:
<composite:implementation>
<composite:insertChildren/>
<h:panelGroup rendered="#{cc.childCount == 0}">
some default data
</h:panelGroup>
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)
任何想法/解决方法?
如何在页面上复合组件的多次使用中仅包含一次JavaScript代码?
最初,我把JS代码放在cc:implementation
标签中,但这导致每次都将组件包含在脚本中.我想避免这种情况,即使组件已在页面上多次使用,也只包含一次JavaScript.
我有以下复合组件:
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute required="true" name="field" />
<composite:attribute required="true" name="value" />
<composite:attribute required="false" name="size"/>
</composite:interface>
<composite:implementation>
...
<div class="wrapper">
<h:inputText value="#{cc.attrs.value}"
id="#{field.id}"
rendered="#{field.rendered}"
size="#{cc.attrs.size}">
</h:inputText>
<h:messages for="#{field.id}" styleClass="errorMessage"/>
</div>
...
</composite:implementation>
</ui:component>
Run Code Online (Sandbox Code Playgroud)
问题是,当我在没有设置其size
属性的情况下使用此组件时,它仍然会像size=0
在html输入元素中一样呈现.
我想要的是h:inputText
只有当它具有有效值(例如,非空)时才渲染嵌套的属性.或者,如果没有显式覆盖嵌套元素的所有属性,我想公开它们的所有属性.
怎么可能?
我在Eclipse中使用JSF 2.0开发了复合组件.我一直把我的XHTML标签文件放在resources
文件夹中.
当我在键盘上按ctrl+ space时,标签的属性不会显示.
我找到一些提示安装"Jboss工具",但没有工作.
<?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:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<cc:interface>
<cc:attribute name="value"/>
<cc:attribute name="label"/>
<cc:attribute name="masculino" default="true"/>
</cc:interface>
<cc:implementation>
<p:selectOneMenu value="#{cc.attrs.value}" label="#{cc.attrs.label}">
<f:selectItem itemValue="#{null}"
itemLabel="#{cc.attrs.masculino ? lbl['LABEL.TODOS'] : lbl['LABEL.TODAS']}" />
<f:selectItem itemValue="true" itemLabel="#{lbl['LABEL.SIM']}" />
<f:selectItem itemValue="false" itemLabel="#{lbl['LABEL.NAO']}" />
</p:selectOneMenu>
</cc:implementation>
</html>
Run Code Online (Sandbox Code Playgroud)
以上是创建的一个标签的一个示例.
谢谢
我的facelet页面中有以下代码:
<hc:rangeChooser1 id="range_chooser"
from="#{testBean.from}"
to="#{testBean.to}"
listener="#{testBean.update}"
text="#{testBean.text}">
<f:ajax event="rangeSelected"
execute="@this"
listener="#{testBean.update}"
render=":form:growl range_chooser"/>
</hc:rangeChooser1>
Run Code Online (Sandbox Code Playgroud)
这是我的复合组件:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<cc:interface componentType="rangeChooser">
<!-- Define component attributes here -->
<cc:clientBehavior name="rangeSelected" event="change" targets="hiddenValue"/>
<cc:attribute name="from" type="java.util.Calendar"/>
<cc:attribute name="to" type="java.util.Calendar"/>
<cc:attribute name="text" type="java.lang.String"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
...
<p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>
...
</div>
</cc:implementation>
</ui:component>
Run Code Online (Sandbox Code Playgroud)
我如何通过属性from
,to
并text
从复合组件支持豆?我的意思是将这些值注入后备组件,而不是通过
<p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>
Run Code Online (Sandbox Code Playgroud)
更新:有更正确的定义是什么,我需要:能够变异这是我从传递对象backing bean
到composite component
内部backing component
的composite component
.因此,当我执行process …
我有以下复合组件(<v2:inputText2>)
<!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:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich">
<!-- INTERFACE -->
<composite:interface>
<composite:attribute name="baseId" required="true" />
<composite:attribute name="size" required="true" />
<composite:attribute name="value" required="true" />
<composite:attribute name="align" required="false" default="" />
<composite:attribute name="label" required="false" default="" />
<composite:attribute name="labelStyle" required="false" default="" />
<composite:attribute name="disabled" required="false" default="false" />
<composite:attribute name="required" required="false" default="false" />
<composite:attribute name="inputStyle" required="false" default="" />
<composite:editableValueHolder name="inTxt" />
</composite:interface>
<!-- IMPLEMENTATION -->
<composite:implementation>
<h:panelGroup id="#{cc.attrs.baseId}Dec">
<table class="decTable" style="align:#{cc.attrs.align};" border="1">
<tr>
<td class="labelSize" style="vertical-align: middle;"> …
Run Code Online (Sandbox Code Playgroud) 我有一个复合组件,其接口包含:
<cc:attribute name="model"
shortDescription="Bean that contains Location" >
<cc:attribute name="location" type="pkg.Location"
required="true" />
</cc:attribute>
</cc:interface>
Run Code Online (Sandbox Code Playgroud)
所以我可以使用#{cc.attrs.model.location}访问标记中的Location对象.
我也从复合组件的支持bean访问该对象,如下所示:
FacesContext fc = FacesContext.getCurrentInstance();
Object obj = fc.getApplication().evaluateExpressionGet(fc,
"#{cc.attrs.model.location}", Location.class);
Run Code Online (Sandbox Code Playgroud)
所以现在我的复合组件已经完成了它的工作 - 如何从支持bean调用模型上的setter方法?(即model.setLocation(someValue)?
我正在开发一个JSF2/Primefaces应用程序,我在访问此组件的支持bean中复合组件的接口中定义的属性时遇到问题.
我的组件定义如下:
<!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:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="testComponent">
<composite:attribute name="text" required="true" type="java.lang.String" />
</composite:interface>
<composite:implementation>
<h:outputText value="Passed text is: #{cc.attrs.text}" />
</composite:implementation>
</html>
Run Code Online (Sandbox Code Playgroud)
它存储在名为text.xhtml
:application/src/main/webapp/resources/my_component
directory 的文件中.
我在另一个页面(这是一个Facelets组合元素)上使用此组件,如下所示:
<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:myc="http://java.sun.com/jsf/composite/my_component"
template="./resources/templates/template.xhtml">
<ui:define name="content">
<h:form id="products">
<myc:test id="test" text="A text" />
</h:form>
</ui:define>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
支持组件类定义如下:
package my.application.component;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@FacesComponent ( value="testComponent" )
public class TestComponent extends UINamingContainer {
Logger log = …
Run Code Online (Sandbox Code Playgroud) 我必须将复合组件迁移到自定义组件.此示例相当简化,但演示了问题:我的component(my:test
)的子节点需要在另一个组件中呈现.my:testC
作为一个我不想使用的例子,复合材料看起来像这样
<composite:implementation>
<p:panel>
<composite:insertChildren/>
</p:panel>
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)
显然,(我希望至少我这个假设是正确的),我不能简单地呈现p:panel
在encodeBegin
.
@FacesComponent("test")
public class Test extends UIPanel
{
@Override
public void encodeBegin(FacesContext context) throws IOException
{
// ??
}
@Override
public void encodeEnd(FacesContext context) throws IOException
{
// ??
}
}
Run Code Online (Sandbox Code Playgroud)
我希望以my:test
这样的方式使用:
<my:test>
<h:outputText value="some Text"/>
</my:test>
Run Code Online (Sandbox Code Playgroud)
输出应该与使用相同my:testC
:在PrimeFaces面板中呈现的一些文本.如何编码p:panel
Java类的用法?
因此,经过几天的调试,我们最终能够重现复合组件之间的一些奇怪的交互ui:repeat
,p:remoteCommand
以及我们不理解的JSF中的部分状态保存.
复合组件使用迭代对象列表ui:repeat
.在每次迭代期间,包含另一个复合组件并传递参数.
<ui:composition (...)>
<ui:repeat var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam"/>
Run Code Online (Sandbox Code Playgroud)
在包含的复合组件中,有一个自动运行p:remoteCommand
调用方法,该方法使用组件接口中定义的参数.
<ui:component (...)>
<p:remoteCommand actionListener="#{someBean.someMethod(cc.attrs.someParam)}"
autoRun="true"
async="true"
global="false">
Run Code Online (Sandbox Code Playgroud)
但是,在设置断点时someMethod(...)
,会传递一个空字符串.仅当部分状态保存设置为false时才会发生这种情况.
我们尝试了几种解决方案,以下方案似乎有效(但我们不明白为什么,也无法预见可能发生的任何其他问题):
我们可以将部分状态保存设置为true
.
我们可以将复合组件模式更改为ui:include
.
我们可以删除一个或两个复合组件,而是直接包含内容.
题
为什么JSF会这样做?复合组件ui:repeat
和参数传递之间的这种交互是什么,这取决于我们是否使用ui:include
/部分状态保存?
我们使用的是Primefaces 5.3,Glassfish 4.1,Mojarra 2.2.12,Java 8.
jsf ×7
jsf-2 ×7
primefaces ×2
ajax ×1
attributes ×1
eclipse ×1
facelets ×1
java ×1
mojarra ×1
uirepeat ×1