JSF2 <h:selectOneMenu 和 <f:ajax 侦听器在 PrettyFaces 过滤器导航之后未调用
Posted
技术标签:
【中文标题】JSF2 <h:selectOneMenu 和 <f:ajax 侦听器在 PrettyFaces 过滤器导航之后未调用【英文标题】:JSF2 <h:selectOneMenu and <f:ajax listeners not called after PrettyFaces Filter Navigation 【发布时间】:2012-04-21 13:37:36 【问题描述】:在使用 JSF + PrettyFaces 处理导航和 bean 操作时遇到 Java Web App 问题。
使用版本:
JSF - 2.1 PrettyFaces - 3.3.3
使用来自链接的 PrettyFaces 过滤器处理导航时发生错误:
<div class="product_img">
<pretty:link mappingId="viewProduct">
<img src="#request.contextPath/image?id=#product.mainImage.fileReference.id" />
<f:param value="#productMB.filters.productCategoryName" />
<f:param value="#product.name" />
</pretty:link>
</div>
pretty-config.xml 映射为:
<url-mapping id="viewProduct">
<pattern value="/shop/product/# productCategoryName : productMB.filters.productCategoryName /# productName : productMB.filters.productName /" />
<view-id value="/pages/productDetails.faces" />
<action>#productMB.openProductDetails</action>
</url-mapping>
豆行动:
public String openProductDetails()
if (filters.getProductCategoryName() != null && !filters.getProductName().equals(""))
loadProductDetailsByName(filters.getProductCategoryName());
return "/pages/productDetails.faces";
用户进入产品详细信息页面,在那里他可以选择颜色、尺寸等产品功能...
<ui:fragment rendered="#productMB.productVO.featureColorAvailable">
<span class="productFeatureLabel">#msg.color</span>
<h:selectOneMenu id="colorSelect"
value="#productMB.productVO.colorSelected"
valueChangeListener="#productMB.colorSelectedValueChanged">
<f:selectItem itemLabel="#msg['select']" noSelectionOption="true" />
<f:selectItems value="#productMB.productFeatureAvailableApplMap['color']" var="colorItem" itemValue="#colorItem"
itemLabel="#msg[colorItem.name]" />
<f:ajax event="valueChange"
listener="#productMB.colorSelectedValueChanged"
render="@this productDetailImage productSubImage productSubImage2 productSubImage3 sizeSelect"></f:ajax>
</h:selectOneMenu>
</ui:fragment>
//... Bean 动作方法
public void colorSelectedValueChanged(ValueChangeEvent event)
if (null != event.getNewValue())
ProductFeatureAppl prodFeatureAppl = (ProductFeatureAppl) event.getNewValue();
filterProductFeatureSelectItem(AppConstants.SIZE, prodFeatureAppl.getProductFeature().getName() );
else
filterProductFeatureSelectItem(AppConstants.SIZE, null );
public void colorSelectedValueChanged(AjaxBehaviorEvent event) throws javax.faces.event.AbortProcessingException
try
if (null != productVO.getColorSelected())
ProductFeatureAppl prodFeatureAppl = productVO.getColorSelected();
filterProductFeatureSelectItem(AppConstants.SIZE, prodFeatureAppl.getProductFeature().getName() );
String prodFeatName = prodFeatureAppl.getProductFeature().getName();
// switch selected pics.
productVO.setCurrentDetailImageName(productVO.getProduct().getProductImageByTypeAndFeatureName(
NameConstants.DETAIL, prodFeatName).getFileReference().getId());
productVO.setCurrentBigImageName(productVO.getProduct().getProductImageByTypeAndFeatureName(
NameConstants.BIG, prodFeatName).getFileReference().getId());
else
filterProductFeatureSelectItem(AppConstants.SIZE, null );
filterProductFeatureSelectItem(AppConstants.COLOR, null );
// reset to default
productVO.setCurrentDetailImageName(productVO.getProduct().getProductImageByType(ProductImageType.DETAIL1.toString()).getFileReference().getId());
productVO.setCurrentBigImageName(productVO.getProduct().getProductImageByType(ProductImageType.BIG1.toString()).getFileReference().getId());
catch (Exception ex)
addErrorMessage(getMessage("error"));
if (screenComponent.isDisplayException())
addErrorMessage(ex.getMessage());
第一次导航到产品详细信息页面后,无论何时从 selectOneMenu id="colorSelect" 不调用 valueChangeListener 和 ajax 监听器。除此之外,还会调用 productMB.openProductDetails 操作。
ajax 调用已完成,我在日志中没有看到任何错误,但没有调用任何侦听器方法。 有人知道为什么会跳过这些 JSF ajax 侦听器吗?
提前致谢。
【问题讨论】:
【参考方案1】:如果您直接从 URL 访问该页面是否可以正常工作?如果 PrettyFaces 被禁用,它会起作用吗?
我怀疑这是链接或 PrettyFaces 的问题。我敢打赌,这与 AJAX 和部分状态保存有关。
这可能与此有关:
public String openProductDetails()
if (filters.getProductCategoryName()
!= null && !filters.getProductName().equals(""))
loadProductDetailsByName(filters.getProductCategoryName());
return "/pages/productDetails.faces"; // why is this being returned?
您正在那里返回一个页面名称。 PrettyFaces 实际上可能会尝试在此字符串上导航。如果您希望显示您在映射中配置的页面,只需返回 null、返回 "" 空字符串或不返回任何内容。
希望这会有所帮助。
【讨论】:
我改方法返回null;现在调用了侦听器,但在 JSF 生命周期中仍然为 HTTP POST Ajax 请求调用 productMB.openProductDetails()。我尝试更改: <filter><filter-name>Pretty Filter</filter-name><filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class><async-supported>false-supported> </async-supported></filter>
为真和假,也没有解决。我还尝试更改 PrettyFilter 的过滤器映射以包括 ASYNC 和 INCLUDE 的调度程序,但添加或删除这些并没有解决问题。
我找到了在任何 ajax 请求之后调用 productMB.openProductDetails 的原因,我添加了 #productMB.openProductDetails。我相信我必须将 onPostback=false 包含在所有具有 ajax 组件的页面中。你知道这是否是关于 Ajax 调用和 PrettyFaces 的正确陈述吗?提前致谢。
是的,这是正确的,因为 JSF AJAX 请求实际上使用的是 HTTP POST。以上是关于JSF2 <h:selectOneMenu 和 <f:ajax 侦听器在 PrettyFaces 过滤器导航之后未调用的主要内容,如果未能解决你的问题,请参考以下文章
<h:selectOneMenu> 为所有下拉列表调用值更改侦听器,而不仅仅是当前
如何使用自定义 JSF 转换器将 h:selectOneMenu 项转换为 List<String>?
h:selectOneMenu 中的 f:ajax 监听方法没有执行