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

2023-09-10 20:21:17 作者:13.初相遇

我有切换前后两个图像之间被点击时,pretty的简单的复合组件。当我点击它的第一次,它工作正常。之后每次,没有任何反应。的toggleSingleSelect被调用,但在面板本身不重新呈现

singleMultiSelectText.xhtml:

 < CC:界面组件类型=singleMultiSelect>

< / CC:接口>

< CC:实施>

    < H:panelGroup中的id =singleMultiSelectPanel的styleClass =场的布局=块>

        < H:的commandButton的styleClass =切换
                         图像=#{cc.singleSelect?
                                  /resources/img/expand-single.gif:
                                  /resources/img/collapse-single.gif'}">
            < F:AJAX监听=#{cc.toggleSingleSelect}
                    执行=@这个渲染=singleMultiSelectPanel/>
        < / H:的commandButton>

    < /小时:panelGroup中>

< / CC:实施>
 

singleMultiSelect.java:

  @FacesComponent(值=singleMultiSelect)
公共类SingleMultiSelect扩展UINamingContainer {

私人布尔singleSelect = TRUE;

公共无效toggleSingleSelect(AjaxBehaviorEvent事件){
    singleSelect =! singleSelect;
}
 

}

中控台有以下输出,当我点击它的第一次:

 更新[assetSearchForm:j_idt112:_t113]:其中,输入级=切换ID =assetSearchFor ....
更新[javax.faces.ViewState]:-4115183671224810146:2892643767875659913 ....
 
在js中的全局变量 在ajax中怎么引用

之后,每次,虽然,我只是得到:

 更新[javax.faces.ViewState]:-4115183671224810146:2892643767875659913 ....
 

解决方案

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:

How to save state when extending UIComponentBase