Sink JSF 2.0复合组件事件在父页面Backing Bean中 [英] Sink JSF 2.0 Composite Component Event in Parent Page Backing Bean

查看:156
本文介绍了Sink JSF 2.0复合组件事件在父页面Backing Bean中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于在父页面中使用JSF 2.0复合组件,我有一个概念性的思维块。我了解如何为复合组件的操作实现ActionListener(以及其他),但是如何为父页面配置消费者?例如,我希望我的登录组合组件执行身份验证,完成后,通过一个事件(ActionListener?)通知父页面的备份bean来执行一些UI初始化工作。这里的关键是登录组件会说:嘿,我已经完成,用户很好,轮到你。



提前感谢协助。 / p>

Peace。



Chris

解决方案

我发现一种方法可以使用复合组件+自定义组件类型+ ActionSource2 +系统事件



在你的组合的界面中设置一个组件类型(当不确定时,实现(Mojarra或MyFaces)使用默认组件类型。

 < cc:interface componentType =example.Login> 
< cc:attribute name =texttype =java.lang.String/>
< cc:attribute name =actionExpressionmethod-signature =void method()/>
< / cc:interface>

< cc:implementation>
< p>
< h:outputLabel value =User/>
< h:inputText id =user/>
< / p>
< p&g t;
< h:outputLabel value =密码/>
< h:inputSecret id =password/>
< / p>
< / cc:implementation>

此组件类型是实现NamingContainer的一个java类(UINamingContainer是实现此接口的组件的子类) 。接下来,您必须实施ActionSource2,以便在用户验证时可以生成一个操作事件。



验证必须在用户和密码组件被验证之后(而不是您的验证但JSF过程验证)。为了知道何时发生验证,我们使用系统事件。



这是自定义组件的代码示例。该类实现了ActionSource2接口的方法,并覆盖了广播来处理ActionEvent。我在Mojarra中使用一些特定的类(因为ActionSource和ActionSource2之间的遗留)。

  @FacesComponent(example.Login) //组合中的组件类型
@ListenerFor(systemEventClass = PostValidateEvent.class)//侦听用户和密码验证的事件
public class LoginComponent扩展UINamingContainer实现ActionSource2 {

@Override
public void processEvent(ComponentSystemEvent event)throws AbortProcessingException {
if(event instanceof PostValidateEvent){
System.out.println(post validate);
}
super.processEvent(event);
String user =(String)((HtmlInputText)findComponent(user))。getValue();
String password =(String)((HtmlInputSecret)findComponent(password))。getValue();
System.out.println(user:+ user);
System.out.println(password:+ password);
//一个简单的验证逻辑
if(user!= null&& user.equals(victor)&& password!= null&& password.equals )){
System.out.println(user ok);
queueEvent(new ActionEvent(this));
}
}


private MethodExpression exp;

@Override
public MethodExpression getActionExpression(){
return exp;
}

@Override
public void setActionExpression(MethodExpression action){
exp = action;
}

@Override
public MethodBinding getAction(){
return exp!= null?新的MethodBindingMethodExpressionAdapter(exp):null;
}

@Override
public void setAction(MethodBinding action){
setActionExpression(new MethodExpressionMethodBindingAdapter(action));
}

private MethodBinding actionListener;

@Override
public MethodBinding getActionListener(){
return actionListener;
}

@Override
public void setActionListener(MethodBinding actionListener){
this.actionListener = actionListener;
}

private boolean i;

@Override
public boolean isImmediate(){
return i;
}

@Override
public void setImmediate(boolean immediate){
this.i = immediate;
}

列表< ActionListener> listeners = new LinkedList< ActionListener>();

@Override
public void addActionListener(ActionListener listener){
listeners.add(listener);
}

@Override
public ActionListener [] getActionListeners(){
return listeners.toArray(new ActionListener [0]);
}

@Override
public void removeActionListener(ActionListener listener){
listeners.remove(listener);
}

@Override
public void broadcast(FacesEvent event)throws AbortProcessingException {
super.broadcast(event);

if(Event instanceof ActionEvent){
FacesContext context = getFacesContext();
MethodBinding binding = getActionListener();
if(binding!= null){
binding.invoke(context,new Object [] {event});
}

ActionListener listener = context.getApplication()。getActionListener();
if(listener!= null){
listener.processAction((ActionEvent)event);
}
}
}

}

这是使用页面中的代码:

 < ez:login actionExpression =#{bean.logged }/> 


I have a conceptual mind-block around the use of a JSF 2.0 composite component within a parent page. I understand how to implement an ActionListener (and others) for a composite component's action but how is this wired-up for the parental page to consume? For example, I want my login composite component to perform authentication and when complete, inform the parent page's backing bean through the an event (ActionListener?) to do some UI initialization work. The key here is the login component would say, "Hey, I'm done and the user is good. Your turn."

Thanks in advance for the assistance.

Peace.

Chris

解决方案

One way I found you can acomplish this is using composite component + custom component type + ActionSource2 + system events.

In the interface of your composite set a component-type (when not definied, the implementation (Mojarra or MyFaces) uses a default component type.

<cc:interface componentType="example.Login">
  <cc:attribute name="text" type="java.lang.String"/>
  <cc:attribute name="actionExpression" method-signature="void method()"/>
</cc:interface>

<cc:implementation>
    <p>
      <h:outputLabel value="User"/>
      <h:inputText id="user"/>
    </p>
    <p>
      <h:outputLabel value="Password"/>
      <h:inputSecret id="password"/>
    </p>
</cc:implementation>

This component type is a java class that implements NamingContainer (UINamingContainer is a subclass of component implementing this interface). Next you have to implement ActionSource2 so you could generate an action event when the user is verified.

The verifyng must be after the user and password components have been validated (not your verification but JSF PROCESS VALIDATIONS). In order to know when the validation has occurs, we use System Events.

This is an example of the code for the custom component. The class implements the methods of the ActionSource2 interface and overrides broadcast to handle ActionEvent's. I use some specific classes in Mojarra (because the legacy between ActionSource and ActionSource2).

 @FacesComponent("example.Login") //Component type in the composite
@ListenerFor(systemEventClass=PostValidateEvent.class) //Event to listen for user and password verification
public class LoginComponent extends UINamingContainer implements  ActionSource2{

    @Override
    public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
        if(event instanceof PostValidateEvent){
            System.out.println("post validate");
        }
        super.processEvent(event);
        String user=(String) ((HtmlInputText)findComponent("user")).getValue();
        String password=(String) ((HtmlInputSecret)findComponent("password")).getValue();
        System.out.println("user: "+user);
        System.out.println("password: "+password);
        //a simple logic for verification
        if(user != null && user.equals("victor") && password != null && password.equals(user)){
            System.out.println("user ok");
            queueEvent(new ActionEvent(this));
        }
    }


    private MethodExpression exp;

    @Override
    public MethodExpression getActionExpression() {
        return exp;
    }

    @Override
    public void setActionExpression(MethodExpression action) {
        exp=action;
    }

    @Override
    public MethodBinding getAction() {
        return exp != null ? new MethodBindingMethodExpressionAdapter(exp): null;
    }

    @Override
    public void setAction(MethodBinding action) {
        setActionExpression(new MethodExpressionMethodBindingAdapter(action));
    }

    private MethodBinding actionListener;

    @Override
    public MethodBinding getActionListener() {
        return actionListener;
    }

    @Override
    public void setActionListener(MethodBinding actionListener) {
        this.actionListener=actionListener;
    }

    private boolean i;

    @Override
    public boolean isImmediate() {
        return i;
    }

    @Override
    public void setImmediate(boolean immediate) {
        this.i=immediate;
    }

    List<ActionListener> listeners=new LinkedList<ActionListener>();

    @Override
    public void addActionListener(ActionListener listener) {
        listeners.add(listener);
    }

    @Override
    public ActionListener[] getActionListeners() {
        return listeners.toArray(new ActionListener[0]);
    }

    @Override
    public void removeActionListener(ActionListener listener) {
        listeners.remove(listener);
    }

    @Override
     public void broadcast(FacesEvent event) throws AbortProcessingException {
        super.broadcast(event);

        if (event instanceof ActionEvent) {
            FacesContext context = getFacesContext();
            MethodBinding binding = getActionListener();
            if (binding != null) {
                binding.invoke(context, new Object[] { event });
            }

            ActionListener listener = context.getApplication().getActionListener();
            if (listener != null) {
                listener.processAction((ActionEvent) event);
            }
        }
    }

}

And this is the code in the using page:

<ez:login actionExpression="#{bean.logged}"/>

这篇关于Sink JSF 2.0复合组件事件在父页面Backing Bean中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆