Component Objects and Component State
In WebObjects, state can also be scoped to a component, such as a dynamically generated page or a reusable component within a page. Common uses for component state include storing:
- A list of items that a user can choose from within a particular page
- The user's selection from that list
- Information that the users enters in a form
- Default values for a component's attributes
A simple example of component state can be seen in the first page of the DodgeLite sample application, which lists models, prices, and types of vehicles for the user to choose from (see Figure 32).
// Java DodgeLite Main.java ImmutableVector models, prices, types; MutableVector selectedModels, selectedPrices, selectedTypes; String model, price, type; public Main() { super(); java.util.Enumeration en; Application woApp = (Application)application(); en = woApp.modelsDict().elements(); models = new MutableVector(); while (en.hasMoreElements()) ((MutableVector)models).addElement(en.nextElement()); en = woApp.typesDict().elements(); while (en.hasMoreElements()) ((MutableVector)types.addElement(en.nextElement()); prices = woApp.prices(); }The selectedModels, selectedPrices, and selectedTypes instance variables are bound to the selections attributes of the three WOBrowsers and so will contain the user's selections when the Display Cars button is clicked.
// WebScript DodgeLite Main.wos id models, model, selectedModels; id prices, price, selectedPrices; id types, type, selectedTypes; - init { id anApplication = [WOApplication application]; [super init]; models = [[anApplication modelsDict] allValues]; types = [[anApplication typesDict] allValues]; prices = [anApplication prices]; return self; }
When a user starts a session of the DodgeLite application, the Main component's initialization method is invoked, initializing the component's instance variables from data accessed through the application object. From this point on, the Main component and its instance variables become part of the state stored for that user's session of the DodgeLite application. When the session is released, the component is also released. However, there are other techniques that allow you to control resource allocation on a component basis, as you'll see later in this chapter.
As with the session state, a component's state is accessible to other objects within the same session. As the result of a user's action, for example, it's quite common for one component to create the component for the next page and set its state. Looking again at the DodgeLite application, consider what happens when the user makes a selection in the first page and clicks Display Cars. The displayCars method in the Main component is invoked:
// Java DodgeLite Main.java public Component displayCars() { SelectedCars selectedCarsPage = (SelectedCars)application().pageWithName("SelectedCars"); ... selectedCarsPage.setModels(selectedModels); selectedCarsPage.setTypes(selectedTypes); selectedCarsPage.setPrices(selectedPrices); ... selectedCarsPage.fetchSelectedCars(); return (Component)selectedCarsPage; }The new component is created by sending a pageWithName: message to the application object. A series of messages is then sent to this new object to set its state before the object is returned as the response page.
// WebScript DodgeLite Main.wos - displayCars { id selectedCarsPage = [[self application] pageWithName:@"SelectedCars"]; ... [selectedCarsPage setModels:selectedModels]; [selectedCarsPage setTypes:selectedTypes]; [selectedCarsPage setPrices:selectedPrices]; ... [selectedCarsPage fetchSelectedCars]; return selectedCarsPage; }
Component state persists until the component object is deallocated, an action that can occur for various reasons, as described in the section "Controlling Component State".
Table of Contents Next Section