|
Pages
PagesThe most convenient option to create a page is to simply extend the Page class. The Page class unites the IPage and IPageSupplier interfaces and provides it's subclasses with page related data and options. (For instance a page id, a page title, a navigationCommand to change to another page, ...) Each Page subclass corresponds to a previously configured page. When deepsplink boots, it instantiates all configured pages with an IPageSupplier instance as constructor argument. Then it (optionally) injects dependencies using injectors and navigates to the first page. A minimal page looks like this: public class TestPage extends Page {
public function TestPage(supplier : IPageSupplier) {
super(supplier);
}
/**
* create and render the page content
* perhaps create a navigation for the child pages (not shown)
* set the show & hide strategy for the page
*/
override public function initialize() : void {
var btn : SomeBtn = new SomeBtn();
btn.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) : void {
navigationCommand.gotoPage("somePageId")
});
display.addChild(btn);
setShowStrategy(new QTween(display).duration(300).add(QTweenConst.ALPHA, 1));
setHideStrategy(new QTween(display).duration(300).add(QTweenConst.ALPHA, 0));
// When initialization is complete setInitialized must be invoked
setInitialized();
}
/**
* stop current operations
* dispose of the page content
* remove event listeners
* cleanup resources for the garbage colletor
*/
override public function finalize() : void {
while(display.numChildren > 0) {
display.removeChildAt(0);
...
}
}Note that each Page is only instantiated once. Then the page instance stays alive and can adopt different states. You can identify the current page state by invoking the state method inside a Page subclass. Show/Hide strategiesYou can set a show- and a hide strategy for each page. These strategies are responsible for showing and hiding a page. It often happens that several pages show and hide in a similar fashion, so the concept of strategies enables you to reuse this code across pages. Often the strategies are created during initialization of a page: override public function initialize() : void {
setShowStrategy(new ShowStrategy(display));
setHideStrategy(new HideStrategy(display));A custom strategy implementation might look like this: public class ShowStrategy extends Qable implements IQable {
public function ShowStrategy(display : DisplayObject) {
_display = display;
}
// invoked after the setInitialized call inside the corresponding page
override protected function doStart() : void {
if(_display is DisplayObjectContainer) {
for each(var child : DisplayObject in DisplayObjectContainer(_display)) {
tween(child, delay...
}
}
}
}For a more detailed explaination on IQable read more about queues. As the setShowStrategy and the setHideStrategy methods expect an IQable implementation you can also just use a QTween to alpha-tween to whole page display: setShowStrategy(new QTween(display).duration(300).add(QTweenConst.ALPHA, 1)); setHideStrategy(new QTween(display).duration(300).add(QTweenConst.ALPHA, 0));
The Page lifecycleEach page can adopt the following states:
Page activationEach page is instantiated when deepsplink boots. If a page needs to become active, it's initialize method is invoked. Until the page calles setInitialized the page adopts the initializing state. When setInitialized is eventually called, the page state changes to initialized. Next the showStrategy of the page is started and the page state changes to showing. Upon showStrategy completion, the page state changes to shown. Page deactivationIf a page needs to become inactive, it's hideStrategy is started and the page state changes to hiding. When the hideStrategy completes, the page state changes to hidden. Lastly the finalize method of the page is invoked and after the finalize method has been executed the page state changes to finalized. Page request ordering:Pages are arranged in a tree. The tree consists of page branches which all lead up to a root page. If a page is active, all pages between the active page and the root page are active too. All pages outside this branch are inactive: root
page1 (active)
page2 (active)
page3 (active)
page4 (inactive)
page5 (inactive)If the user navigates from one page branch to another, the current branch is hidden and the new branch is shown: root
page1 hide->inactive
page2 hide->inactive
page3 hide->inactive
page4 show->active
page5 show->activeNow you can control the order in which page branches are activated and deactivated with the aid of request builders. The default request builder is the "hide-initshow-finalize" request builder. If no request is configured, this default request builder is used. You can configure such a request builder for each page. This request builder is then used for each of the child pages until another request builder turns up inside one of the child pages. Suppose the following configuration (irrelevant attributes are left out) : <page id="root" request="hide-initshow-finalize"> <page id="home" > <page id="page1" /> <page id="page2" > <page id="page3" /> </page> </page> </page> Assuming the currently active page is page1 and a change to page3 is requested, the request builder is looked up from the target page (page3) point of view. The page3 branch is searched (page2 -> home -> root) for a request builder and eventually the "hide-initshow-finalize" request builder is found on the root page. This request builder builds the request in the the following order:
There are serveral request builders, namely:
Because you can associate a request builder with each page, you can apply different request builders to different page branches. The rules are simple: If a page is requested, it searches it's parent pages until a request builder is found. Then this request builder is used to activate the requested page branch.
Page ParametersPage parameters enable dynamic pages. Imagine a shop with hunderts of products with a details page for each product. It would be a nightmare to declare a product detail page for each product inside the configuration. Instead you just declare one ProcuctDetail page and use page parameters to render the details of different products. So instead of http://www.xyz.com/#product-1-details http://www.xyz.com/#product-2-details http://www.xyz.com/#product-3-details you have: http://www.xyz.com/#product-details?product-id=1 At initialization time the page already knows it's page parameters. So you can use the getParamValueForKey method to retrieve the value for any parameter. override public function initialize() : void {
var productId : String = getParamValueForKey("product-id");
}If the page is already shown and the page parameters change the onParamsChanged method is invoked. So if you need to know when the parameters of a page change, ovverride onParamsChanged. override public function onParamsChanged(params : Array) : void {
var productId : String = getParamValueForKey("product-id");
}To change the parameters of a page yourself you can employ the navigationCommand var params : Array = new Array();
params.push(new PageParameter("product-id", "2");
params.push(new PageParameter("anotherParam", "anotherValue");
navigationCommand.gotoPage("somePageId", params);If the parameters of a page change actually the parameters of all active pages change. So a complete page branch can react on a page parameter change. The onParamsChanged method is always invoked starting with the root page and ending with the topmost active page. |