我正在尝试使用复合组件事件更新父组件f:ajax.
复合组件在这里:
<cc:interface>
<cc:attribute name="update" />
<cc:attribute name="customid" required="true"/>
<cc:attribute name="val" required="true"/>
<cc:attribute name="selectedvalue" required="true"/>
</cc:interface>
<cc:implementation>
<h:panelGrid columns="2" style="font-size: 10px" >
<p:selectOneMenu id="#{cc.attrs.customid} value="#{cc.attrs.selectedvalue}">
<f:selectItems value="#{cc.attrs.val}"/>
<f:ajax event="change" render="#{cc.attrs.update" />
</p:selectOneMenu>
<p:commandButton type="button" icon="ui-icon-plus" onclick="dlg.show();" />
</h:panelGrid>
</cc:implementation>
Run Code Online (Sandbox Code Playgroud)
现在使用此组件时如下:
<h:form>
<ez:combo customid="make" val="#{vehicleBean.makes}" selectedvalue="#vehicleBean.vehicle.make}" update="model" />
<p:selectOneMenu id="model" value="#{vehicleBean.vehicle.model}">
<f:selectItems value="#{vehicleBean.models}" />
</p:selectOneMenu>
</h:form>
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
包含一个未知的id"模型" - 无法在组件make的上下文中找到它
我想在我的JSF复合组件中实现一些javas cript,但我有id的问题.我的java脚本:
document.getElementById("myForm:customerId")
Run Code Online (Sandbox Code Playgroud)
不起作用,因为id是错误的.我有JSF复合组件:
<composite:implementation>
<div id="element_customer">
<h2 class="element_title">Customer</h2>
<h:form id="myForm">
<h:inputText id="customerId" value="#{cc.attrs.customerId}"/>
</h:form>
</div>
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)
和HTML输出是:
<div id="element_customer">
<h2 class="element_title">Customer</h2>
<form id="j_idt44:myForm" name="j_idt44:myForm" method="post" ... >
<input type="hidden" name="j_idt44:myForm" value="j_idt44:myForm" />
<input id="j_idt44:myForm:customerId" ... name="j_idt44:myForm:customerId" />
</form>
</div>
Run Code Online (Sandbox Code Playgroud)
为什么HTML输出中使用"j_idt44"?
我已经创建了一些Facelets来使我们的页面更容易开发.特别是,我为输入组件创建了一系列Facelets.我有1个Facelet,<xxx:input />它在输入字段周围显示一个标签.除此之外,我有Facelets喜欢<xxx:inputText />和<xxx:inputSecret />渲染实际的输入字段.这些中的每一个都<xxx:input />用于显示标签.Facelet看起来像这样:
<html ...>
<composite:interface>
...
</composite:interface>
<composite:implementation>
<label><h:outputText value="#{cc.attrs.labelText}" /></label>
<composite:insertChildren />
</composite:implementation>
</html>
Run Code Online (Sandbox Code Playgroud)
在<xxx:inputText />随后的facelet是这样的......
<html ...>
<composite:interface>
...
</composite:interface>
<composite:implementation>
<xxx:input labelText=...>
<h:inputText id="myinput" ... />
</xxx:input>
</composite:implementation>
</html>
Run Code Online (Sandbox Code Playgroud)
一切都很好,但我在尝试添加<f:validator />或其他验证标签时遇到麻烦.根据我的阅读,我必须在我的Facelet中添加一个标签.所以,我<composite:editableValueHolder name="myinput" targets="myinput" />在界面部分添加了一行.但是,我仍然没有看到我的验证器被解雇.我的.xhtml文件中有这样的东西......
...
<xxx:inputText value="...">
<f:validateLength minimum="10" for="myinput" />
</xxx:inputText>
...
Run Code Online (Sandbox Code Playgroud)
无论我输入什么输入,验证器似乎永远不会触发,我永远不会收到错误消息.同事建议这是由于我使用的目标ID以及它被<xxx:input />Facelet 包裹的事实.
我是否需要在目标定义中包含父组件ID?还有别的东西让我失踪吗?如果我排除<xxx:input />Facelet,它的工作正常,所以我假设它与之相关,但不知道如何解决它.非常感谢您提供的任何帮助.
我正在编写一个需要与我的DAO交互的(复合)组件.以下是声明Java部分的方式:
@FacesComponent(value="selectLocation")
public class SelectLocation extends UINamingContainer {
Run Code Online (Sandbox Code Playgroud)
为了获取DAO对象,我尝试了CDI注释:
@Inject private LocationControl lc;
Run Code Online (Sandbox Code Playgroud)
这没用,所以我尝试了Faces注释:
@ManagedProperty (value = "@{locationControl}") private LocationControl lc;
Run Code Online (Sandbox Code Playgroud)
两种情况都没有发生 - 属性lc在构造函数完成后最终为null.
我在所有的后台bean中使用CDI,一切正常.这将使用GlassFish 3.1.1中的Weld.有关如何获取资源的任何建议?
如何在页面上复合组件的多次使用中仅包含一次JavaScript代码?
最初,我把JS代码放在cc:implementation标签中,但这导致每次都将组件包含在脚本中.我想避免这种情况,即使组件已在页面上多次使用,也只包含一次JavaScript.
我仍然不确定正确使用JSF模板和复合组件.我需要创建一个企业Web应用程序,它将拥有大量页面.每个页面都有相同的标题,菜单,页脚,当然还有不同的内容(= JSF模板).每个页面上的内容将由可重复使用的"框"(= JSF复合组件)组成.这些盒子包括一些文件,按钮等.我的解决方案是否合适?或者我应该使用其他技术,如自定义组件,装饰......?
layout.xhtml
<h:body>
<ui:insert name="main_menu">
<ui:include src="/xhtml/template/main_menu.xhtml"/>
</ui:insert>
<ui:insert name="header">
<ui:include src="/xhtml/template/header.xhtml"/>
</ui:insert>
<ui:insert name="content"/>
<ui:insert name="footer">
<ui:include src="/xhtml/template/footer.xhtml"/>
</ui:insert>
</h:body>
Run Code Online (Sandbox Code Playgroud)
customer_overview.xhtml:
<html xmlns:cc="http://java.sun.com/jsf/composite/composite_component">
<h:body>
<!-- Facelet template -->
<ui:composition template="/xhtml/template/layout.xhtml">
<ui:define name="content">
<!-- Composite Components -->
<cc:component_case_history
caseList="#{customerOverviewController.cases}"
/>
<cc:component_customer
....
/>
...
</ui:define>
</ui:composition>
</h:body>
Run Code Online (Sandbox Code Playgroud)
component_case_history.xhtml
<html xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="cases" type="java.util.List"/>
</composite:interface>
<composite:implementation>
<!-- using of "cases" -->
...
</composite:implementation>
Run Code Online (Sandbox Code Playgroud)
CustomerOverviewController.java
@ManagedBean
@ViewScoped
public class CustomerOverviewController {
public List<Case> getCases() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2012-04-27 …
我试图找出这是一个JSF/EL问题还是错在这里.
基本上,我想将一个项目对象作为ui:param传递给一个ui:组合并在里面有一个按钮(即bootstrap按钮,因此它们实际上是html链接因此使用commandLink)并让它使用该项目执行一个动作PARAM.这是ui:composition item.xhtml传递了一些参数.
<ui:include src="comp/item.xhtml">
<ui:param name="item" value="#{itemVM.item}"/>
<ui:param name="desc" value="#{true}"/>
</ui:include>
Run Code Online (Sandbox Code Playgroud)
现在我希望这个按钮是一个复合组件"bt:button",但是它似乎在解决"item"参数时遇到了问题.为了确认这一点,我将命令链接从组件中取出并放在页面上,确定它有效.此外,如果我在ui:composition之外移动bt:按钮,它也可以在那里工作.最后,如果我使用单引号(如'test')将item更改为字符串,那么它也可以正常工作(出于测试目的,我的action方法需要一个Object).基于这三种情况,看起来复合组件在解析传递给合成的项参数时遇到问题.
这是item.xhtml中第一个测试(即复合组件与常规JSF命令链接相对)的示例:
<!- This composite component doesn't Work -->
<bt:button id="cmpBtn" active="#{user.compares[item.id]}"
disabled="#{user.compares[item.id] != null and itemsCtr.numOfCompares >= 100}"
styleClass="btn-item-compare btn-small"
style="margin-bottom:5px"
action="#{itemsCtr.compare(item)}">
<i class="#{user.compares[item.id] != null ? 'icon-minus' : 'icon-plus'}"/>
<h:outputText value="#{user.compares[item.id] != null ? 'Comparing' : 'Compare'}"/>
<f:ajax render="@this"/>
</bt:button>
<!-- This regular jsf component works -->
<h:commandLink action="#{itemsCtr.compare(item)}" value="Test">
<f:ajax render="@this"/>
</h:commandLink>
Run Code Online (Sandbox Code Playgroud)
这是我的bt:button的复合组件定义:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:f="http://java.sun.com/jsf/core">
<cc:interface componentType="LinkComponent">
<cc:attribute name="action" targets="button"/>
<cc:attribute name="value" …Run Code Online (Sandbox Code Playgroud) 我正在使用动态仪表板,用户可以根据需要固定和删除项目.现在我遇到一个问题,我想将现有的复合组件添加到支持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:cc="http://java.sun.com/jsf/composite"
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:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<h:outputText value="TEST"/>
</cc:implementation>
</html>
Run Code Online (Sandbox Code Playgroud)
这是应该返回复合组件的代码:
public static UIComponent getCompositeComponent(String xhtml, String namespace) {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
Resource componentResource = app.getResourceHandler().createResource(xhtml, namespace);
UIPanel facet = (UIPanel) app.createComponent(UIPanel.COMPONENT_TYPE);
facet.setRendererType("javax.faces.Group");
UIComponent composite = app.createComponent(fc, componentResource);
composite.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facet);
return composite;
}
Run Code Online (Sandbox Code Playgroud)
这是我如何使用该功能:
Column column = new Column();
UIComponent test …Run Code Online (Sandbox Code Playgroud) 注意:我使用的是mojarra 2.1.20和丰富的面孔4.2.2.
我已经分析了一个堆转储,我注意到EL表达式驻留在会话中的LRUMap中.有谁知道为什么以及如何避免它?
我遇到的问题与包含以下行的复合组件有关:
<rich:select ... valueChangeListener="#{cc.listValuesChangeListener}"
Run Code Online (Sandbox Code Playgroud)
使用支持bean my.package.MultiComboSelection.显然my.package.MultiComboSelection有一个名为listValuesChangeListener的方法.
我看到的问题是LRUMap包含ContextualCompositeMethodExpression(上面的valueChangeListener表达式的表示),cc属性引用MultiComboSelection.MultiComboSelection扩展了UINamingContainer,因此具有父/子属性 - 引用了组件树.
结果是16MB的内存不能被垃圾收集,因为有一个参考链:
session-> LRUMap-> ContextualCompositeMethodExpression-> MultiComboSelection-> parent和16MB
问题是 - 为什么会发生这种情况以及如何解决或解决它?
Class Name | Shallow Heap | Retained Heap | Retained Heap
--------------------------------------------------------------------------------------------------------------------------------------------
my.package.MultiComboSelection @ 0x78dc2bd50 | 96 | 16 466 272 | 16 466 272
|- component javax.faces.component.UIComponentBase$FacetsMap @ 0x78dbbbd58 | 48 | 128 |
|- parent javax.faces.component.UIPanel @ 0x78dbbbdd8 | 88 | 760 |
|- cc com.sun.faces.facelets.el.ContextualCompositeMethodExpression @ 0x78dc2bce0 | 32 | 16 466 384 |
| |- …Run Code Online (Sandbox Code Playgroud) ORIGINAL JSP(WorkItem.jsp)
<c:forEach var="actionItem" items="${workItem.work_action_list}">
<c:if test="${actionItem.workActionClass.work_action_type_id == '1'}" >
<%@ include file="inc_done_button.jsp" %>
</c:if>
<c:if test="${actionItem.workActionClass.work_action_type_id == '2'}" >
<c:set var="actionItem" value="${actionItem}" scope="request" />
<c:set var="checklist" value="${actionItem.meat}" scope="request" />
<jsp:include page="inc_dynamic_checklist_v.jsp" flush="true" />
</c:if>
etc...
</c:forEach>
Run Code Online (Sandbox Code Playgroud)
原始Java
for (ListIterator<WorkflowInstanceWorkItemAction> actionIter = wfiwi.getWork_action_list().listIterator(); actionIter.hasNext();) {
if ("2".equals(work_action_type_id)) {
ChecklistInstanceForm ciForm = new ChecklistInstanceForm(this, authenticatedUser);
ChecklistInstance ci = null;
ci = (ChecklistInstance) ciForm.getChkLstInstanceByWfiWiaOwner(wfiWorkItemAction, authenticatedUser);
// Get the meat details for this action and inject it into the object
wfiWorkItemAction.setMeat(ci);
} …Run Code Online (Sandbox Code Playgroud)