在JSF 2.1中调用操作方法后,绑定组件未更新

时间:2014-09-18 10:31:34

标签: jsf-2

我已动态构建了一个组件以满足我的要求。单击commandlink时,应更新绑定组件,但不会更新。在action方法之前调用组件getter方法(即在Restore_View阶段)。 buf在动作方法之后,没有调用getter方法(我的意思是在Render_Response阶段)。

请注意,我的支持bean范围是请求。

请找到以下测试代码XHTML

<h:form id="testForm">
    <!-- Filters Links-->
    <h:panelGroup id="dynaComp" layout="block" 
                  binding="#{testBean.panelGroup}"
                  />
</h:form>

请找到以下支持bean代码

package com.kosna.test;

import com.ocpsoft.pretty.faces.annotation.URLAction;
import com.ocpsoft.pretty.faces.annotation.URLMapping;
import java.util.Arrays;
import javax.el.ELContext;
import javax.el.MethodExpression;
import javax.faces.component.behavior.AjaxBehavior;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;

/**
 *
 * @author KOSNA
 */
@URLMapping(id = "test", pattern = "/test",
        viewId = "/faces/test.xhtml")
public class TestBean {

private HtmlPanelGroup panelGroup;

private ELContext elContext;

private int itemCount = 2;

// Constructor
public TestBean() {
    elContext = FacesContext.getCurrentInstance().getELContext();
}

// pretty link action method 
@URLAction(mappingId = "test", onPostback = false)
public void preparePage() {
    updateComponent();
    // include test.xhtml page;
}

private void updateComponent() {
    panelGroup = new HtmlPanelGroup();
    panelGroup.setId("parentPanel");
    buildMoreLink(panelGroup);
    while (itemCount >= 0) {
        HtmlOutputText text = new HtmlOutputText();
        text.setId("test_" + itemCount);
        text.setValue("test" + itemCount);
        panelGroup.getChildren().add(text);
        itemCount--;
    }

}

private void buildMoreLink(HtmlPanelGroup headingGrp) {
    HtmlCommandLink link = new HtmlCommandLink();
    MethodExpression me = FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createMethodExpression(
            elContext, "#{testBean.actionMethod}", String.class, new Class<?>[0]);
    HtmlOutputText outText = new HtmlOutputText();
    AjaxBehavior ab = new AjaxBehavior();
    ab.setImmediate(true);
    // I tried with appending formID also
    ab.setRender(Arrays.asList("parentPanel"));
    ab.setExecute(Arrays.asList("@this"));
    outText.setEscape(false);
    outText.setValue("More");
    link.addClientBehavior("click", ab);
    link.getChildren().add(outText);
    link.setActionExpression(me);
    headingGrp.getChildren().add(link);

}

public String actionMethod() {
    setItemCount(5);
    updateComponent();
    return "pretty:test";
}

public HtmlPanelGroup getPanelGroup() {
    if(null == panelGroup) {
        updateComponent();
    }
    return panelGroup;
}

public void setPanelGroup(HtmlPanelGroup panelGroup) {
    this.panelGroup = panelGroup;
}

public int getItemCount() {
    return itemCount;
}

public void setItemCount(int itemCount) {
    this.itemCount = itemCount;
}

}

请告诉我为什么在actionMethod之后没有更新组件?

1 个答案:

答案 0 :(得分:0)

1)组件的getter不应包含任何其他代码。所有业务逻辑应仅在动作侦听器(updateComponent())中。

public HtmlPanelGroup getPanelGroup() {
    return panelGroup;
}

2)你不应该手动创建panelGroup而是使用一次JSF创建并始终更新它。

private void updateComponent() {
    buildMoreLink(panelGroup);
    while (itemCount >= 0) {
        HtmlOutputText text = new HtmlOutputText();
        text.setId("test_" + itemCount);
        text.setValue("test" + itemCount);
        panelGroup.getChildren().add(text);
        itemCount--;
    }
    RequestContext context = RequestContext.getCurrentInstance();
    context.update(panelGroup.getClientId());
} 

也许,这个带组件绑定的例子也很有用:http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html

<强> EDITED

要在更新操作上呈现panelGroup,您可以写:

private void updateComponent() {
    ...
    RequestContext context = RequestContext.getCurrentInstance();
    context.update(panelGroup.getClientId());
}