集成JSF与BEEHIVE PAGE FLOW之二

从后台bean访问当前页面流或共享流
  在某些情况下,您或许想直接从后台bean访问当前页面流或一个活动的共享流。为此,只需创建一个适当类型的字段,并使用@Jpf.PageFlowField或@Jpf.SharedFlowField对其进行适当注释:

@Jpf.CommandHandler(
raiseActions={
      @Jpf.RaiseAction(action="goPage3")
}
)
public String chooseNextPage()
{
return "goPage3";
}

  这些字段将在创建后台bean的时候被初始化。无需手动对其进行初始化。下面的例子使用了自动初始化的ExampleController字段。在这个例子中,“show hints”单选钮的事件处理程序在页面流中设置了一个普通优先级。

@Jpf.PageFlowField
private ExampleController myController;

@Jpf.SharedFlowField(name="sharedFlow2") // "sharedFlow2" is a
                              // name defined in the
                              // page flow controller
private ExampleSharedFlow mySharedFlow;


  在很多情况下,页面不需要直接与页面流或者共享流进行交互;使用其它方法从页面流向JSF页面传递数据就足够了,反之亦然。下面我将给出一些例子。

  从页面流控制器访问后台bean
  您不能从页面流控制器访问后台bean!至少,这不容易做到,这是有意为之的。后台bean与JSF页面紧密相关,当您离开页面的时候,后台bean会被销毁。正如页面流控制器不应了解页面细节一样,它也不应了解后台bean。当然了,可以从后台bean向控制器传递数据(稍后将会介绍),甚至可以传递后台bean实例本身,但是在大多数情况下,后台bean的内容是不应当泄露给控制器的。

  生命周期方法
  通常,当后台bean发生某些事情的时候,比如当它被创建或销毁时,我们希望能运行代码。在Page Flow框架的生命周期中,它会对后台bean调用一些方法:

onCreate():创建bean时
onDestroy():销毁bean时(从用户会话移除)
onRestore():这个需要详细解释一下。我说过,当您离开页面的时候,后台bean会被销毁。在大多数情况下是这样的,但是如果页面流使用了navigateTo特性(它使您可以再次访问先前显示的页面),在您离开页面之后,Page Flow框架会保留后台bean一小段时间,以防它需要还原。当通过@Jpf.Forward或@Jpf.SimpleAction使用navigateTo=Jpf.NavigateTo.currentPage或navigateTo=Jpf.NavigateTo.previousPage还原一个JSF页面时,页面的组件树及其后台bean都被Page Flow框架还原。当这种情况发生时,onRestore()就被调用。
  不管要在哪个时期运行代码,只需重写适当的方法:

protected void onCreate()
{
/*some create-time logic */
}
  当重写这些方法时,不需要调用空的super版本。

  在JSF页面和页面流之间传递数据
  现在我们该看看如何在JSF页面和页面流之间传递数据了。

  从页面流向JSF页面发送数据
  通常,您会想要利用页面流的数据来初始化一个页面。为此,可以向page2.faces的Forward添加“action outputs”:

@Jpf.Action(
forwards={
@Jpf.Forward(
    name="success", path="page2.faces",
    actionOutputs={
      @Jpf.ActionOutput(name="message", type=String.class,required=true)
    }
)
}
)

public Forward goPage2()
{
Forward fwd = new
Forward("success");
   fwd.addActionOutput("message", "Got the message.");
return fwd;
}

  做完这些之后,可以直接从JSF页面或者后台bean将该值作为页面输入来访问。(如果您不喜欢键入冗长的注释,可以省去斜体的。它们主要用于再次检查添加的对象类型是否正确,确定不缺失类型。)

  可以在页面中利用JSF表示语言中的页面流pageInput绑定上下文绑定到这个值:

<h:outputText value="#{pageInput.message}"/>
  注意,可以利用pageFlow和sharedFlow绑定上下文绑定到页面流控制器自身或者任何可用的共享流的属性:

<h:outputText value="#{pageFlow.someProperty}"/>
<h:outputText value="#{sharedFlow.mySharedFlow.someProperty}"/>
  最后,要想从后台bean访问页面输入,只需在bean类代码中的任意地方调用getPageInput:

String message = (String) getPageInput("message");
  从JSF页面向页面流发送数据
  还可以随着页面流所引发的动作发送数据。很多动作将要求表单bean作为输入;通常,表单bean用于从页面获取数据送到控制器。首先,让我们构建一个动作来接收表单bean并跳转到页面:

@Jpf.Action(
   forwards={
       @Jpf.Forward(name="success", path="page3.faces")
   }
)
public Forward goPage3(NameBean nameBean)
{
    _userName = nameBean.getFirstName() + ' ' +
                nameBean.getLastName();
    return new Forward("success");
}

  该动作包含一个NameBean,它是一个将getters/setters作为其firstName和lastName属性的表单bean类。它设置一个成员变量保存完整名字,之后跳转到page3.faces。我们知道,可以直接从JSF页面或者它的后台bean引发一个动作。在这两种情况下,都可以向动作发送表单bean。下面让我们依次看看每种情况。

  从后台bean发送表单bean
  要从后台bean中的命令处理程序发送表单bean,需要使用一个特定的注释。下面给出了page2.java中的情况:

private ExampleController.NameBean _nameBean;

protected void onCreate()
{
    _nameBean = new ExampleController.NameBean();
}

public ExampleController.NameBean getName()
{
    return _nameBean;
}

@Jpf.CommandHandler(
    raiseActions={
        @Jpf.RaiseAction(action="goPage3",
             outputFormBean="_nameBean")
    }
)
public String chooseNextPage()
{
    return "goPage3";
}

  在这个例子中,JSF页面可以用它选择的任何方式填充_nameBean的值(例如,通过将h:inputText值绑定到#{backing.name.firstName}和#{backing.name.lastName})。之后它使用@Jpf.RaiseAction上的outputFormBean属性来标记_nameBean应当被传递到动作goPage3。

  从JSF页面发送表单bean
  从JSF页面直接发送表单bean很容易,只要您可以通过数据绑定表达式得到bean值。这是通过在commandButton组件内部添加名为submitFormBean的h:attribute组件来实现的:

<h:commandButton action="#{backing.chooseNextPage}"
                 value="Submit directly from page">
    <f:attribute name="submitFormBean" value="backing.name" />
</h:commandButton>
  在这里,为了使表单bean发送到动作goPage3,按钮绑定到后台bean的“name”属性(getName)。

你可能感兴趣的:(bean,框架,JSF,活动)