且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

AJAX调用切换复合成分布尔变量似乎工作只有一次

更新时间:2022-12-26 17:18:04

JSF组件在每个请求的视图生成时创建的。换句话说,JSF组件实例基本上请求范围。

singleSelect 属性需要在回传被保留在同样的观点。换句话说,你希望它是视图范围。

不过,您分配它作为组件的一个实例变量,而不是明确地将其保存在JSF视图状态。所以,每一个请求时,它会重新初始化回,并有效地成为每一次它的默认值,你preSS的按钮。

您需要明确地保存视图在JSF视图状态范围内的状态。您可以使用继承 getStateHelper() 方法这一点。

 公共无效toggleSingleSelect(AjaxBehaviorEvent事件){
    setSingleSelect(isSingleSelect()!);
}

公共无效setSingleSelect(布尔singleSelect){
    。getStateHelper()把​​(singleSelect,singleSelect);
}

公共布尔isSingleSelect(){
    返程(布尔)getStateHelper()的eval(singleSelect,真正的)。
}
 

参见:

  • How延长UIComponentBase
  • 在当前保存状态

I have a pretty simple composite component which toggles back and forth between two images when it is clicked. When I click it the first time, it works fine. Every time after that, nothing happens. The "toggleSingleSelect" is called, but the panel itself is not re-rendered.

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;
}    

}

The console has the following output when I click it the first time:

update["assetSearchForm:j_idt112:_t113"]: <input class="toggle" id="assetSearchFor....
update["javax.faces.ViewState"]: -4115183671224810146:2892643767875659913....

Every time after that, though, I just get:

update["javax.faces.ViewState"]: -4115183671224810146:2892643767875659913....

JSF components are created during view build time of every request. In other words, JSF component instances are basically request scoped.

Your singleSelect property needs to be retained across postbacks on the same view. In other words, you want it to be view scoped.

However, you assigned it as an instance variable of the component instead of explicitly saving it in the JSF view state. So, during every request, it would reinitialize back to its default value of true, and effectively become false every time you press the button.

You need to explicitly save view scoped state in the JSF view state. You can use the inherited getStateHelper() method for this.

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);
}

See also: