Ajax 切换复合组件布尔变量的调用似乎只工作一次
Ajax call to toggle a composite component boolean variable seems to work only once
我有一个非常简单的复合组件,当它被点击时,它会在两个图像之间来回切换。当我第一次点击它时,它工作正常。此后每次都没有任何反应。 "toggleSingleSelect" 被调用,但面板本身并未重新呈现。
singleMultiSelectText.xhtml:
<cc:interface componentType="singleMultiSelect">
</cc:interface>
<cc:implementation>
<h:panelGroup id="singleMultiSelectPanel" styleClass="field" layout="block">
<h:commandButton styleClass="toggle"
image="#{cc.singleSelect ?
'/resources/img/expand-single.gif' :
'/resources/img/collapse-single.gif'}">
<f:ajax listener="#{cc.toggleSingleSelect}"
execute="@this" render="singleMultiSelectPanel"/>
</h:commandButton>
</h:panelGroup>
</cc:implementation>
singleMultiSelect.java:
@FacesComponent(value = "singleMultiSelect")
public class SingleMultiSelect extends UINamingContainer {
private boolean singleSelect = true;
public void toggleSingleSelect(AjaxBehaviorEvent event) {
singleSelect = ! singleSelect;
}
}
第一次点击控制台输出如下:
update["assetSearchForm:j_idt112:_t113"]: <input class="toggle" id="assetSearchFor....
update["javax.faces.ViewState"]: -4115183671224810146:2892643767875659913....
不过,之后的每一次,我都会得到:
update["javax.faces.ViewState"]: -4115183671224810146:2892643767875659913....
JSF 组件是在每个请求的视图构建期间创建的。换句话说,JSF 组件实例基本上是请求范围的。
您的 singleSelect
属性 需要在同一视图的回传中保留。换句话说,您希望它在视图范围内。
但是,您将其指定为组件的实例变量,而不是将其显式保存在 JSF 视图状态中。因此,在每次请求期间,它会重新初始化为默认值 true
,并在您每次按下按钮时有效地变为 false
。
您需要在 JSF 视图状态中显式保存视图范围状态。您可以为此使用继承的 getStateHelper()
方法。
public void toggleSingleSelect(AjaxBehaviorEvent event) {
setSingleSelect(!isSingleSelect());
}
public void setSingleSelect(boolean singleSelect) {
getStateHelper().put("singleSelect", singleSelect);
}
public boolean isSingleSelect() {
return (boolean) getStateHelper().eval("singleSelect", true);
}
另请参阅:
- How to save state when extending UIComponentBase
我有一个非常简单的复合组件,当它被点击时,它会在两个图像之间来回切换。当我第一次点击它时,它工作正常。此后每次都没有任何反应。 "toggleSingleSelect" 被调用,但面板本身并未重新呈现。
singleMultiSelectText.xhtml:
<cc:interface componentType="singleMultiSelect">
</cc:interface>
<cc:implementation>
<h:panelGroup id="singleMultiSelectPanel" styleClass="field" layout="block">
<h:commandButton styleClass="toggle"
image="#{cc.singleSelect ?
'/resources/img/expand-single.gif' :
'/resources/img/collapse-single.gif'}">
<f:ajax listener="#{cc.toggleSingleSelect}"
execute="@this" render="singleMultiSelectPanel"/>
</h:commandButton>
</h:panelGroup>
</cc:implementation>
singleMultiSelect.java:
@FacesComponent(value = "singleMultiSelect")
public class SingleMultiSelect extends UINamingContainer {
private boolean singleSelect = true;
public void toggleSingleSelect(AjaxBehaviorEvent event) {
singleSelect = ! singleSelect;
}
}
第一次点击控制台输出如下:
update["assetSearchForm:j_idt112:_t113"]: <input class="toggle" id="assetSearchFor....
update["javax.faces.ViewState"]: -4115183671224810146:2892643767875659913....
不过,之后的每一次,我都会得到:
update["javax.faces.ViewState"]: -4115183671224810146:2892643767875659913....
JSF 组件是在每个请求的视图构建期间创建的。换句话说,JSF 组件实例基本上是请求范围的。
您的 singleSelect
属性 需要在同一视图的回传中保留。换句话说,您希望它在视图范围内。
但是,您将其指定为组件的实例变量,而不是将其显式保存在 JSF 视图状态中。因此,在每次请求期间,它会重新初始化为默认值 true
,并在您每次按下按钮时有效地变为 false
。
您需要在 JSF 视图状态中显式保存视图范围状态。您可以为此使用继承的 getStateHelper()
方法。
public void toggleSingleSelect(AjaxBehaviorEvent event) {
setSingleSelect(!isSingleSelect());
}
public void setSingleSelect(boolean singleSelect) {
getStateHelper().put("singleSelect", singleSelect);
}
public boolean isSingleSelect() {
return (boolean) getStateHelper().eval("singleSelect", true);
}
另请参阅:
- How to save state when extending UIComponentBase