Table of Contents Previous Section
Direct Actions
If you want your application to perform direct action request handling instead of component action request handling (as described in "The Request-Response Loop"), you place your action methods in a different class and you write them slightly differently.
With direct actions, there is no concept of a request page that can perform the requested action. (Recall from the previous section that the Main component is the request page for the sayHello action, meaning that Main implements the sayHello method.) Instead, the direct action method is defined in a subclass of WODirectAction.
myForm : WOForm {Direct action method names are derived from action names by appending "Action" to the action name. Thus, setting your element's directActionName attribute to "sayHello" as in the above code causes MyAction's sayHelloAction method to be invoked when the WOSubmitButton is clicked.
actionClass = "";
}
button : WOSubmitButton {
directActionName = "sayHello";
actionClass = "MyAction";
}
The WODirectAction class is simply a container for action methods. When you create a WebObjects application project in Project Builder, you automatically get a subclass of WODirectAction named DirectAction (DirectAction is the default name for the WODirectAction subclass; you can rename it, if you prefer). Each action method in your WODirectAction class must end with the string "Action" and should return either a WOComponent or a WOResponse object. For example:
- (WOComponent *)sayHelloActionor:
public WOComponent sayHelloAction()Note that your application can use as many WODirectAction subclasses as necessary.
Your direct action method should return an object that conforms to the WOActionResults protocol (Java interface); typically, your method will return a WOComponent or a WOResponse (both implement the methods in WOActionResults). Unlike component actions, direct actions may not return nil or null.
To use a more complete illustration, in an implementation of the HelloWorld application using direct actions the Main component's declarations file might look like this:
myForm : WOForm {The actionClass and directActionName attributes specify that clicking this hyperlink should trigger the MyAction object's sayHelloAction method. Note that WOForms cannot have submit buttons to both component and direct actions. Because of this, when using a submit button bound to a direct action the WOForm must be triggered to cooperate. You do this by having an empty binding for direct action, as shown in the previous code excerpt, or by just putting the action directly on the WOForm.
directActionName = "";
}
textField : WOTextField {
value = visitorNameIVar;
name = "visitorName";
}
button : WOSubmitButton {
directActionName = "sayHello";
actionClass = "MyAction";
}
The implementation of sayHelloAction is similar to the implementation of sayHello shown in the previous section. It creates a new page named Hello and sends that page the name the user has typed into the text field.
//WebScript DirectAction.wosWhere sayHelloAction differs from sayHello is that it must perform an additional step: it must extract the form values out of the request itself. The visitor's name is recorded in an instance variable in the Main component (visitorNameIVar in the example above). With component actions, any action that is performed by a dynamic element in Main is implemented in Main's code. Because the action is implemented in Main, you can reference the instance variable directly. Direct actions are performed in a separate class and do not have access to Main's instance variables. Instead, direct action methods must extract the information they need from the HTTP request. In this example, the visitor's name is recorded in a text field named "visitorName." Thus, sayHelloAction asks for the value for "visitorName" from the request and passes that value to the Hello component.
- (WOComponent *)sayHelloAction
{
id nextPage;
id aName = [[self request] formValueForKey:@"visitorName"];
nextPage = [self pageWithName:@"Hello"];
[nextPage setVisitorName:aName];
return nextPage;
} //Java DirectAction.java
public WOComponent sayHelloAction() {
Hello nextPage;
String aName = (String)request().formValueForKey("visitorName");
nextPage = (Hello)this.pageWithName("Hello");
nextPage.setVisitorName(aName);
return (WOComponent)nextPage;
}
Table of Contents Next Section