【问题标题】:JSF custom panel with button - action not invoked带有按钮的 JSF 自定义面板 - 未调用操作
【发布时间】:2012-08-17 07:55:06
【问题描述】:

我已经构建了一个自定义组件按钮,但不知何故没有调用该操作。在组件中调试 getAction-Method 并调用提供的 MethodeExpression 时,Bean-Method 会按预期调用。但是由于某种原因,在浏览器中按下按钮时没有调用表达式。

是否需要某种额外的接口才能将操作传递给嵌入式按钮组件?

非常感谢任何帮助,因为我已经被这个问题困扰了好几天了

我的班级:

public class MyClass extends UIPanel implements SystemEventListener
{

private UIForm              form;
private HtmlCommandButton   buttonOk;

public MyClass()
{
    FacesContext context = getFacesContext();
    UIViewRoot root = context.getViewRoot();
    root.subscribeToViewEvent(PostAddToViewEvent.class, this);
}


@Override
public void processEvent(SystemEvent event)
{
    this.form = new UIForm();
    this.buttonOk = new HtmlCommandButton();
    this.buttonOk.setId("okButtonId");
    this.buttonOk.setActionExpression(getAction());
    this.buttonOk.setValue("OK");
    this.form.getChildren().add(this.buttonOk);
    getChildren().add(this.form);
}


private enum PropertyKeys
{
    action, text, titel
}


public MethodExpression getAction()
{
    return (MethodExpression) getStateHelper().eval(PropertyKeys.action);
}


public void setAction(MethodExpression actionExpression)
{
    getStateHelper().put(PropertyKeys.action, actionExpression);
}


public String getText()
{
    return (String) getStateHelper().eval(PropertyKeys.text);
}


public void setText(String text)
{
    getStateHelper().put(PropertyKeys.text, text);
}


public String getTitel()
{
    return (String) getStateHelper().eval(PropertyKeys.titel);
}


public void setTitel(String titel)
{
    getStateHelper().put(PropertyKeys.titel, titel);
}


@Override
public void encodeAll(FacesContext context) throws IOException
{
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement(HTML.DIV_ELEM, this);
    writer.writeText(getText(), null);
    this.form.encodeAll(context);
    writer.endElement(HTML.DIV_ELEM);
}


@Override
public void encodeChildren(FacesContext context) throws IOException
{

}


@Override
public boolean isListenerForSource(Object source)
{
    return (source instanceof MyClass);
}

}

MyClassHandler:

public class MyClassHandler extends ComponentHandler
{

public MyClassHandler(ComponentConfig config)
{
    super(config);
}


@SuppressWarnings("rawtypes")
@Override
protected MetaRuleset createMetaRuleset(Class type)
{
    return super.createMetaRuleset(type).addRule(new MethodRule("action", String.class, new Class[] { ActionEvent.class }));
}

}

myView 方法:

...
public String myMethod()
{
    System.err.println("myMethod");
    return "/some/path/yadayada.xhtml";
}
...

MyView.xhtml

<myTag action="#{myView.myMethod}" id="id1" titel="bla" text="bleh" />

【问题讨论】:

    标签: button jsf-2 action


    【解决方案1】:

    扩展 UICommand 就足够了,因为您只希望执行一个操作。

    您必须通过标记属性提供两个额外的 MethodExpression,并且在 decode-method 中,您可以检查哪个按钮已被按下并将特定的 MethodExpression 重定向到 UICommand 提供的标准操作。这样,您就不必担心旧接口 ActionSource 或事件的广播方式。

    public void decode(FacesContext contex)
    {
        Map<String,String> map = context.getExternalContext.getRequestParameterMap();
        // your rendered buttons need a name you check for
        final boolean okPressed = map.containsKey( getClientId + ":ok" ); 
        final boolean cancelPressed = map.containsKey( getClientId + ":cancel" );
        if(okPressed || cancelPressed)
        {
            MethodExpression exp = null;
            if(okPressed)
            {
                exp = getActionOk();
            }
            else
            {
                exp = getActionCancel();
            }
            // redirect to standard action
            setActionExpression(exp);
            queueEvent(new ActionEvent(this));
        }
    }
    

    为了利用这一点,您需要两个使用方法表达式(setter 和 getter)的属性(actionOk 和 actionCancel)。这些必须由 ComponentHandler 配置,就像您为操作属性所做的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 2019-10-28
      • 2013-03-03
      • 2015-06-26
      • 1970-01-01
      • 2014-08-08
      • 1970-01-01
      相关资源
      最近更新 更多