Oracle® Application Development Framework Developer's Guide
10g Release 3 (10.1.3) B25386-01 |
|
Previous |
Next |
Instead of explicitly specifying a static outcome value in a navigation component, you can dynamically determine the outcome by binding the action
attribute of a navigation component to an action method. An action method is a method in a backing bean (also known as a managed bean) that can perform an action (such as saving user input) and return an outcome value. The outcome value determines the next page that should be displayed after the method performs an action. For example, an action method that verifies user input on a page might return one outcome if the input is valid and return another outcome if the input is invalid. Each of these different outcomes could trigger different navigation cases, causing the application to navigate to one of two possible target pages. As with static outcomes, a dynamic outcome triggers a navigation case that contains a matching from-outcome
value or a default navigation case.
The method bound to a navigation component must be a public method with no parameters, and it must return a String
representing the outcome of the action. An action method can return one of multiple outcomes depending on the processing it carries out. In other words, you can define conditional outcomes in the method logic. The outcome returned by the method must be defined in one of the cases in the page's navigation rules (unless you are using default rules, which handle all outcomes not specified in any navigation case).
Tip: In ADF applications, most processing of data objects is handled by methods on the data control. Therefore, if a navigation component that uses dynamic outcomes needs to perform some processing on a data object (for example, creating, editing, deleting), it should be bound to a backing bean method that injects the ADF binding container. When a backing bean injects the ADF binding container, it calls the specified data control method to handle the processing of the data and then, based on the results, returns a navigation outcome to the UI component. For more information about injecting the binding container into a backing bean, see Section 10.5, "Overriding Declarative Methods". |
If you want the outcome of a navigation component to be determined dynamically, you can bind the component to a method on a backing bean. The backing bean can execute some application logic and, depending on the results, return an outcome. The returned outcome will determine the navigation rule that is implemented. For information about creating backing beans, see Section 4.5, "Creating and Using a Backing Bean for a Web Page".
To create a navigation component that binds to a backing bean:
From the ADF Faces Core page of the Component Palette, drag a CommandButton or a CommandLink onto the page.
Tip: You can also use the JSFcommandButton and commandLink components.
|
In the visual editor double-click the UI component to display the Bind Action Property dialog, as shown in Figure 9-5.
The Bind Action Property dialog enables you to identify the backing bean and method to which you want to bind the component. If enabled auto-binding when you created the page, the Bind Action Property dialog does not display the option for specifying a static outcome.
In the Bind Action Property dialog, identify the backing bean and the method to which you want to bind the component using one of the following techniques:
Click New to create a new backing bean. The Create Managed Bean dialog is displayed. Use this dialog to name the bean and the class.
Select an existing backing bean and method from the dropdown lists.
After identifying the backing bean and method, click OK on the Bind Action Property dialog.
JDeveloper displays the source editor. If it is a new method, the source editor displays a stub method, as shown in Example 9-13. If it is an existing method, the source editor displays that method, instead of the stub method.
Add any required processing logic to the method.
Change the return values of the method to the appropriate outcome strings.
You may want to write conditional logic to return one of multiple outcomes depending on certain criteria. For example, you might want to return null
if there is an error in the processing, or another outcome value if the processing was successful. A return value of null
causes the navigation handler to forgo evaluating navigation cases and to immediately redisplay the current page.
Tip: To trigger a specific navigation case, the outcome value you enter in theaction attribute must exactly match the outcome value in the navigation rule, including uppercase and lowercase letters.
|
When you create a navigation component that specifies a dynamic outcome, JDeveloper adds an EL expression to the action
attribute of the component tag. The EL expression references the backing bean method that will perform some application processing, such as saving user input, and return an outcome value.
Example 9-14 shows a button on the SRCreateConfirm page of the SRDemo application that uses a dynamic outcome value. The button was created using the ADF Faces commandButton
component, which is available from the Data Control Palette context menu. The user clicks the button to create a new service request.
Example 9-14 Navigation Component That Uses Dynamic Outcomes
<af:commandButton text="#{res['srcreate.submit.button']}" partialSubmit="false" action="#{backing_SRCreateConfirm.createSRButton_action}" id="createSRButton"/>
The button's action
attribute is bound to the createSRButton_action
method on the SRCreateConfirm
backing bean, which is shown in Example 9-15. The backing bean method starts by validating the user input. If the user did not enter a problem description for the service request, the method returns an outcome value of Back
. If the user did enter a problem description, the method creates the service request and returns an outcome value of Complete
. (To create the service request, the method injects the ADF binding container, which calls the createServiceRequest
data control method. For more information about injecting the binding container into a backing bean method, see Section 10.5, "Overriding Declarative Methods".)
Example 9-15 Backing Bean Method That Returns a Dynamic Outcome
public String createSRButton_action() { BindingContainer bindings = getBindings(); //Before we proceed check that the user has entered a description Object description = ADFUtils.getBoundAttributeValue(bindings, "SRCreatePageDef", "problemDescription"); if (description == null) { FacesContext ctx = FacesContext.getCurrentInstance(); ctx.addMessage(null, JSFUtils.getMessageFromBundle("srcreate. missingDescription",FacesMessage.SEVERITY_ERROR)); return "Back"; } else { //now find the facade method binding OperationBinding operationBinding = bindings.getOperationBinding("createServiceRequest"); ServiceRequest result = (ServiceRequest)operationBinding.execute(); //Put the number of the created service ID onto the request as an // example of passing data in that way Integer svrId = result.getSvrId(); ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext(); HttpServletRequest request = (HttpServletRequest)ectx.getRequest(); request.setAttribute("SRDEMO_CREATED_SVRID", svrId); //Force a requery on the next visit to the SRList page UserSystemState.refreshNeeded(); return "Complete"; } }
Example 9-16 shows the navigation rule that handles the two possible outcomes returned by the backing bean.
Example 9-16 Navigation Rule Referenced by a Dynamic Outcome
<navigation-rule> <from-view-id>/SRCreateConfirm.jspx</from-view-id> <navigation-case> <from-outcome>Back</from-outcome> <to-view-id>/SRCreate.jspx</to-view-id> </navigation-case> <navigation-case> <from-outcome>Complete</from-outcome> <to-view-id>/SRCreateDone.jspx</to-view-id> </navigation-case> </navigation-rule>
When a user clicks a navigation component that has a dynamic outcome, the action method on the backing bean is executed. The method usually processes some user input and then returns an outcome value to the page. The JSF navigation handler evaluates the outcome returned by the action method and matches it to a navigation case that has the same value defined in the from-outcome
element. The matching rule is then implemented and the page defined in the rule's to-view-id
element is displayed. If the method does not return an outcome or if the outcome does not match any of the navigation cases, the user remains on the current page.
When using an action method to handle navigation in an application, you don't need to implement an ActionListener
interface to invoke the method because JSF uses a default ActionListener
to invoke action methods for page navigation: the method's logical outcome value is used to tell the JSF navigation handler what page to use for the render response.
If an action method returns different outcomes depending on the processing logic, you may want to define a default navigation case to prevent having the method return an outcome that is not covered by any specific navigation case.
Default navigation cases catch all the outcomes not specifically covered in other navigation cases. To define a default navigation case, you can exclude the from-outcome
element, which tells the navigation handler that the case should apply to any outcome not handled by another case.
For example, suppose you are using an action method to handle a Submit command button. You can handle the success case by displaying a particular page for that outcome. For all other outcomes, you can display a page explaining that the user cannot continue. Example 9-17 shows the navigation cases for this scenario.
Example 9-17 Navigation Rule with a Default Navigation Case
<navigation-rule> <from-view-id>/order.jsp</from-view-id> <navigation-case> <from-action>#{backing_home.submit}</from-action> <from-outcome>success</from-outcome> <to-view-id>/summary.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{backing_home.submit}</from-action> <to-view-id>/again.jsp</to-view-id> </navigation-case> </navigation-rule>
In the example, the first navigation case is a dynamic navigation case, where an action method is determining the outcome. If the outcome is success
, the user navigates to the /summary.jsp
page.
The second navigation case is a default navigation case that catches all other outcomes returned by the action method and displays the /action.jsp
for all outcomes. Notice that the default case does not specify a from-outcome
value, which causes this case to be implemented if the outcome returned by the action method does not match any of the other cases.
You can use action listener methods in a navigation component when you have an action that needs information about the user interface. Suppose you have a button that uses an image of the state of California, and you want a user to be able to select a county and display information about that county. You could implement an action listener method that determines which county is selected by storing an outcome for each county, and an action method that uses the outcome value to navigate to the correct county page.
To use an action method and action listener method on a component, you would reference them as shown in Example 9-18.