@BalusC,这与the post you say不同,因为我问的是actionListener
奇怪的行为没有执行方法。
此外,在我的测试中,我按照Primefaces的文档,将固定id
属性应用于每个NamingContainer
并检查生成的HTML(并具有预期的{{1} }}' S)
你说这个帖子与此重复,这是一个很好的帮助,但我们在这里讨论另一个问题。
我正在使用webapp的布局,发现更新DOM时出现问题。我正在使用 Primefaces 5.2 和 Glassfish 4.1 。为了隔离问题,我尝试在其他项目中测试它,但我在测试中发现了另一个问题。也许我错过了什么,所以我需要在这个论坛上提问。
我会倒退:我会描述测试,然后是真正的问题所以你可以看到它具有相同的结构
id
<h:body>
<h:form id="form-render">
<p:commandButton id="btnRender" value="Render" update=":form-rendered"
actionListener="#{renderView.setRender(true)}"/>
</h:form>
<h:form id="form-rendered">
<h:outputText value="Rendered in form-rendered" rendered="#{renderView.render}"/>
<p:panelGrid id="panel-grid" rendered="#{renderView.render}">
<p:outputLabel value="Rendered in form-rendered:panel-grid"/>
</p:panelGrid>
</h:form>
</h:body>
但是当我运行测试时,只渲染import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class RenderView implements Serializable {
private static final long serialVersionUID = -1687524798440117276L;
private boolean render;
public RenderView() {
this.render = false;
System.out.println("Constructor - render=" + this.render);
}
public boolean isRender() {
return render;
}
public void setRender(boolean render) {
this.render = render;
System.out.println("Setter - render=" + this.render);
}
}
组件。我尝试了另一种选择:
<h:outputText>
:结果相同update=":form-rendered, :form-rendered:panel-grid"
:不会渲染任何内容update=":form-rendered:panel-grid"
属性从rendered=#{...}
移至<p:panelGrid>
内:不会更改我不知道如何引用<p:outputLabel>
中的<p:panelGrid>
。根据{{3}}:
Update属性采用逗号或空格分隔的JSF组件ID列表进行更新
所以第一个选项应该有效,但它没有。我在这里缺少什么?
之前的测试来自我面临的布局问题。布局的想法如下:
<h:form>
(由facelet template client
制作)<ui:composition>
类只是创建虚拟对象来填充Primefaces的组件所以我使用了前一个测试的相同结构来解决每个页面中的问题。有趣的是,我编写了第一个并完美地工作,但是当我编写第二个时,无法渲染第二个表单。 更多的是,我编写了第三个并完美地工作,编码第四个并且失败!!! 。
在我的第一个解决方案尝试中,我使用了以下bean:
@ManagedBean
我首先从一个工作示例中复制粘贴,然后形成一个失败的例子,所以也许你可以看到我失踪的东西。
@ManagedBean // from javax.faces.bean
@ViewScoped // idem
public class SearchView {
private boolean showResults;
public SearchView() {
this.showResults = false;
System.out.println("Constructor-showResults=" + this.showResults);
}
public boolean isShowResults() {
return showResults;
}
public void setShowResults(boolean showResults) {
this.showResults = showResults;
System.out.println("Setter-showResults=" + this.showResults);
}
}
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
template="./../templateMenu.xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<ui:define name="left">
<ui:include src="include/auMenu.xhtml"/>
</ui:define>
<ui:define name="content">
<h1>Search 1</h1>
<h:form id="form-busq-au">
<p:panelGrid columns="2" styleClass="ui-noborder">
<!--form fields -->
<p:commandButton value="Search" icon="ui-icon-search" style="width: 100%;"
actionListener="#{searchView.setShowResults(true)}"
update=":form-res-au"/>
</p:panelGrid>
</h:form>
<h:form id="form-res-au">
<c:if test="#{searchView.showResults}">
<h1>Search Results</h1>
</c:if>
<p:panelGrid id="panelgrid-res-au" columns="2" rendered="#{searchView.showResults}">
<!-- other fields -->
</p:panelGrid>
</h:form>
</ui:define>
</ui:composition>
正如您所看到的,它在测试和两个页面中的结构相同,但行为却不同。我不知道这是否是表面中的错误或什么。
调试代码我意识到在第二页中,<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
template="./../templateMenu.xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<ui:define name="left">
<ui:include src="include/menu.xhtml"/>
</ui:define>
<ui:define name="content">
<h:form id="form-busq-mt">
<h1>Search 2</h1>
<p:panelGrid columns="4" styleClass="ui-noborder">
<!-- form fields -->
<p:commandButton value="Search" icon="ui-icon-search" style="width: 100%;"
actionListener="#{searchView.setShowResults(true)}"
update=":form-res-mt"/>
</p:panelGrid>
</h:form>
<h:form id="form-res-mt">
<c:if test="#{searchView.showResults}">
<h1>Search Results</h1>
</c:if>
<p:panelGrid columns="2" rendered="#{searchView.showResults}">
<!-- Other fields -->
</p:panelGrid>
</h:form>
</ui:define>
</ui:composition>
方法永远不会被调用,不知道为什么。所以我尝试了以下解决方案:
认为这是setSearchResult(true)
Managed Bean的问题,我在Controller中进行了更改:我使用属性和方法创建了一个抽象类,并为每个Web创建了一个SearchView
扩展抽象类的页面。在代码中:
@ManagedBean
对于每个搜索页面:
public abstract class SearchView {
private boolean showResults;
public SearchView() {
this.showResults = false;
System.out.println("Constructor-showResults=" + this.showResults);
System.out.println("Class: " + this.getClass().toString());
System.out.println("ID: " + this.getClass().hashCode());
}
public boolean isShowResults() {
return showResults;
}
public void setShowResults(boolean showResults) {
this.showResults = showResults;
System.out.println("Setter-showResults=" + this.showResults);
}
}
但结果是相同的(在第二页中永远不会调用import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class ConcreteXXXSearchView extends SearchView implements Serializable {
private static final long serialVersionUID = -4717041016001640528L;
}
)。 setShowResult(true)
中的println()
方法是测试我实例化不同的对象(实际上,有不同的对象)。
我尝试了测试选项,但问题出在abstract class SearchView
,因为<p:commandButton>
无效。
我在这里遇到两个问题:
actionListener
,其中包含<h:form>
UIComponent
(NamingContainer
)<p:panelGrid>
感谢任何帮助/指南。提前致谢
在 TEST 和 REAL PROBLEM 中,我使用浏览器检查器检查了 DOM ,setShowResults(true)
属性对于两者都是正确的id
和<h:form id="form-res-mt">
答案 0 :(得分:0)
您在非工作方法中使用了actionListener="#{searchView.setShowResults()}"
。
<p:commandButton value="Search" icon="ui-icon-search" style="width: 100%;"
actionListener="#{searchView.setShowResults()}"
update="form-res-mt"/>
但是,searchView.setShowResults()
方法需要boolean argument
,请将您的代码更改为:
<p:commandButton value="Search" icon="ui-icon-search" style="width: 100%;"
actionListener="#{searchView.setShowResults(true)}"
update="form-res-mt"/>
另外,使用<ui:fragment rendered="yourCondition">
代替<c:if test="condition">
,因为如果组件条件返回false,则它不会附加到组件树。因此无法找到组件在UI树中。