这是我的(简化)问题:
我有一个页面使用了我的2个复合组件:
- CCSelection
- CCDisplay
在CCSelection中,我有一个值列表,每个值都有一个h:commandLink
单击链接时,将使用所选值刷新CCDiaplay组件
为此,CCSelection公开了一个直接链接在每个h:commandLink上的方法属性。使用f:属性将该值赋予方法
在页面支持bean中,我有一个方法(给予CCSelection作为属性),它设置了一个成员。
CCDisplay通过页面成员的getter通过cc:属性获取此值
它有效!
现在,我想说明这种行为
我尝试在CCSelection中为每个h:commandLink放置一个f:ajax ...但是如果我在渲染属性中放置@form或@all,则不会渲染任何内容(但会调用setter方法)。如果我将UIComponent(of Page)的id放到渲染中,我会得到一个nullpointerexception,说明没有为CCDisplay中的NamingContainer定义属性。非常奇怪,因为我没有在CCDisplay中改变任何东西!
我认为解决方案是将f:ajax放在CCSelection中但不在Page中。
因此,可能有两种方法可以实现这一目标:
- CCSelection提出了一个事件f:ajax可以管理......但是如何?
- 使用cc:clientBehaviour进行CCSelection。但是有可能更多地定位1个组件(我有很多h:commandLink,但我只想要1个事件)。
- 其他方式?
这是一个伪代码
page.xhtml
<myComp:ccSelection actionMethod="#{pageBean.select}"
render="#{clientIDHelper.clientId['display']}" />
<h:panelGroup id="diplay" binding="#{clientIDHelper.bindings['display']}">
<myComp:ccDisplay value="#{pageBean.value}" />
</h:panelGroup>
要恢复包含ccDiaplay复合组件的面板的完整clientid,我使用描述here的clientIDMap技术。
PageBean.java
private String _value;
public String getValue() { return _value; }
public void setValue(String value) [ _value = value; }
public void select(String value) {
setValue(value);
}
ccSelection.xhtml
<cc:interface>
<cc:attribute method-signature="void selectAction(String)"
name="actionMethod" />
<cc:attribute name="render" />
</cc:interface>
<cc:implementation>
<t:dataTable value="#{cc.values}"
var="val"
...
>
<h:column>
<t:commandLink actionListener="#{cc.selectionValueListener}"
<f:ajax render="#{cc.attrs.render}" />
<f:attribute name="value"
value="#{val}" />
</t:commandLink>
</h:column>
</t:dataTable>
</cc:implementation>
ccSelection.java
public void selectionValueListener() {
// recover the attribute value
String value = event.getComponent().getAttributes().get("value");
// call the callback method of the page
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression method = (MethodExpression) this.getAttributes().get("actionMethod");
if (method != null)
method.invoke(context.getELContext(), new Object[] {value});
}
我不认为ccDisplay是有用的
所以,如果我没有放f:ajax标签,它就可以了。
当我把f:ajax与渲染指向传递给param的clientId时,我在加载页面时出错。
如果我更改@form或@all的渲染,则调用pageBean.select方法,但不刷新ccDisplay。
答案 0 :(得分:1)
我想我在page.xhtml中看到一点错误。 看你创建组件的时间cc:显示你说:
<cc:attribute method-signature="void selectAction(String)" name="actionMethod" />
这意味着需要一个参数。
但是当你在page.xhtml中调用它时,你会这样做:
<myComp:ccSelection actionMethod="#{pageBean.select}"...
它的支持bean方法是:
public void select(String value) {
setValue(value);
}
如您所见,支持bean是正确的,但是当您在页面中调用组件时,没有参数传递给bean,并且最后从未设置该值。 我认为这可能是其中一个原因。
要解决这个问题,我认为你应该通过以下方式传递价值:
<myComp:ccSelection actionMethod="#{pageBean.select(???Selected value
???)}"...
答案 1 :(得分:0)
行。它解决了......但我不太喜欢它。
你会认为我是个傻瓜:我通过删除&lt;![CDATA围绕我的脚本来解决问题!
我已经发现使用CDATA的一些问题。我不知道这是一个MyFaces错误还是我用错误的方法,比如在复合组件中放入许多带有CDATA的h:outputScript块,但是使用CDATA,我得到错误或无法正常工作。只是删除它,它的工作原理!