Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Button 带有按钮的JSF自定义面板-未调用操作_Button_Jsf 2_Action - Fatal编程技术网

Button 带有按钮的JSF自定义面板-未调用操作

Button 带有按钮的JSF自定义面板-未调用操作,button,jsf-2,action,Button,Jsf 2,Action,我已经构建了一个自定义组件按钮,但不知何故该操作没有被调用。在组件内调试getAction方法并调用提供的MethodeExpression时,将按预期调用Bean方法。但由于某些原因,在浏览器中按下按钮时不会调用表达式 是否需要某种附加接口将操作传递给嵌入式按钮组件 非常感谢您的帮助,因为我已经在这个问题上纠缠了好几天了 MyClass: public class MyClass extends UIPanel implements SystemEventListener { private

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

是否需要某种附加接口将操作传递给嵌入式按钮组件

非常感谢您的帮助,因为我已经在这个问题上纠缠了好几天了

MyClass:

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" />

退出UICommand就足够了,因为您只希望执行一个操作

您必须通过标记属性提供两个额外的MethodExpression,在decode方法中,您可以检查已按下的按钮,并将特定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));
    }
}
公共无效解码(FacesContext-contex)
{
Map Map=context.getExternalContext.getRequestParameterMap();
//渲染的按钮需要检查名称
最终布尔值okPressed=map.containsKey(getClientId+“:ok”);
最终布尔值cancelPressed=map.containsKey(getClientId+“:cancel”);
如果(按OK | |取消按)
{
MethodExpression=null;
如果(按下)
{
exp=getActionOk();
}
其他的
{
exp=getActionCancel();
}
//重定向到标准操作
setActionExpression(exp);
queueEvent(新ActionEvent(this));
}
}
为了利用这一点,您需要两个属性(actionOk和actionCancel),它们使用方法表达式(setter和getter)。这些必须由ComponentHandler进行配置,就像对action属性进行配置一样