Feathers UI
  • Docs
  • API
  • Showcase
  • Blog
  • Community

›UI Components

Introduction

  • Getting Started
  • Installation
  • Create a new project in…

    • Command line terminal
    • HaxeDevelop
    • Moonshine IDE
    • Visual Studio Code

    Build a project targeting…

    • Android
    • iOS
    • Linux
    • macOS
    • Windows
    • Web
  • Introduction to OpenFL

UI Components

  • Intro to UI components
  • Application
  • AssetLoader
  • Button
  • Callout
  • Check
  • ComboBox
  • HDividedBox / VDividedBox
  • Drawer
  • GridView
  • GroupListView
  • ItemRenderer
  • Label
  • LayoutGroup
  • LayoutGroupItemRenderer
  • ListView
  • PageIndicator
  • PageNavigator
  • Panel
  • PopUpListView
  • HProgressBar / VProgressBar
  • Radio
  • RouterNavigator
  • HScrollBar / VScrollBar
  • ScrollContainer
  • HSlider / VSlider
  • StackNavigator
  • TabBar
  • TabNavigator
  • TextArea
  • TextCallout
  • TextInput
  • ToggleButton
  • ToggleSwitch
  • TreeView

Layouts

  • Intro to Layouts
  • AnchorLayout
  • HorizontalLayout
  • HorizontalListLayout
  • HorizontalDistributedLayout
  • ResponsiveGridLayout
  • VerticalLayout
  • VerticalListFixedRowLayout
  • VerticalListLayout
  • VerticalDistributedLayout

Styles and Skins

  • Intro to skins
  • Common shape skins
  • Custom programmatic skins
  • Intro to themes
  • Create a custom theme

Custom UI Components

  • Custom UI components
  • Component lifecycle
  • Custom item renderers
  • Class-based item renderers

Miscellaneous

  • CLI commands
  • Collections
  • haxedef options
  • Install Prerelease Builds
Edit

How to use the RouterNavigator component

The RouterNavigator class supports navigation between views by integrating with the HTML History API. On other targets, Feathers UI emulates the behavior of the HTML History API to provide a consistent experience across all platforms.

RouterNavigator is designed for use in web browsers, but it is supported on all platform targets. If your app is not intended for deployment to the web, you might consider using StackNavigator instead, which offers more powerful features that are not supported by the HTML History API.

The Basics

Start by creating a RouterNavigator, and add it to the display list.

var navigator = new RouterNavigator();
this.addChild(navigator);

A view can be a Feathers UI component or any OpenFL display object. The following example creates a simple view with a label.

class HelloView extends LayoutGroup {
    public function new() {
        super();

        var message = new Label();
        message.text = "Hello World";
        this.addChild(message);
    }
}

To add a new view that the navigator can show, create a Route and pass it to the navigator's addRoute() method.

var route = Route.withClass("/", HelloView);
navigator.addRoute(route);

The first argument passed to Route.withClass() is the pathname to use for the view. A pathname must start with a forward slash / character. /settings, /, and /users/list are all examples of valid pathnames.

The pathname is one of several parts of a URL, as demonstrated in the following table.

protocolhostnameportpathnamesearchhash
https:www.google.com443/search?q=feathers+ui#nav

/search is the pathname for https://www.google.com:443/search?q=feathers+ui#nav.

The second argument is the HelloView class from earlier. The navigator will automatically create an instance of this class when the view needs to be shown.

The Route class defines three static functions for creating items.

  • withClass() accepts any subclass of DisplayObject. Each time that the view is shown, a new instance of the class will be instantiated.
  • withFunction() accepts a function that returns a display object. Each time that the view is shown, this function will be called. Using a function can be useful for adding children to a view or setting its properties before showing it in the navigator.
  • withDisplayObject() accepts an already-instantiated display object. When the view is shown, the same instance will always be reused. This one can allocate a lot of memory if overused, so be careful!

Navigation

In a RouterNavigator component, navigating to a new view adds a new entry to the web browser's history. When the user navigates back or forward, the page's URL will be updated, and the RouterNavigator will update the currently displayed view to match.

Navigation may be triggered progammatically by calling functions like push() and goBack() on the navigator.

navigator.push("/users/list");

However, the real power of RouterNavigator comes from using events to trigger navigation.

Navigate with events

The navigator can listen for events dispatched by the active view to automatically trigger navigation to other views. Custom events may be registered with a Route, and a variety of different actions are available, including the ability to push new locations or to go back in history.

Consider the following two views, ViewA and ViewB.

class ViewA extends LayoutGroup {
    public static final PATHNAME = "/";

    public function new() {
        super();
        this.layout = new VerticalLayout();

        var label = new Label();
        label.text = "A";
        this.addChild(label);

        var button = new Button();
        button.text = "Push B";
        button.addEventListener(TriggerEvent.TRIGGER, button_triggerHandler);
        this.addChild(button);
    }

    private function button_triggerHandler(event:TriggerEvent):Void {
        this.dispatchEvent(new Event(Event.CHANGE));
    }
}

ViewA displays a label with the text "A" and a button with the text "Push B". When the button is triggered, ViewA dispatches Event.CHANGE. The pathname of ViewA is /.

class ViewB extends LayoutGroup {
    public static final PATHNAME = "/b";

    public function new() {
        super();
        this.layout = new VerticalLayout();

        var label = new Label();
        label.text = "B";
        this.addChild(label);

        var button = new Button();
        button.text = "Go back to A";
        button.addEventListener(TriggerEvent.TRIGGER, button_triggerHandler);
        this.addChild(button);
    }

    private function button_triggerHandler(event:TriggerEvent):Void {
        this.dispatchEvent(new Event(Event.COMPLETE));
    }
}

ViewB displays a label with the text "B" and a button with the text "Go back to A". When the button is triggered, ViewB dispatches Event.COMPLETE. The pathname of ViewB is /b.

In the next example, the two views are added to the navigator using their pathnames.

var routeA = Route.withClass(ViewA.PATHNAME, ViewA, [
    Event.CHANGE => Push(ViewB.PATHNAME)
]);
navigator.addRoute(routeA);

var routeB = Route.withClass(ViewB.PATHNAME, ViewB, [
    Event.COMPLETE => Push(ViewA.PATHNAME)
]);
navigator.addRoute(routeB);

When creating a Route, a mapping of events to actions may be optionally provided. The available actions are defined on the RouterAction enum.

In the example above, when ViewA dispatches Event.CHANGE, the navigator will create a new history entry for the pathname of ViewB. The Push() action accepts the pathname of the view to push. In this case, it's ViewB.PATHNAME.

Similarly, when ViewB dispatches Event.COMPLETE, the navigator will create a new history entry for ViewA.PATHNAME.

Why does B navigating back to A use Push() too? Shouldn't it use GoBack() instead?

Consider how you would create a simple HTML website. You want a.html to link to b.html, so you'd add <a href="b.html">Push B</a>. Similarly, if b.html should link to a.html, you'd add <a href="a.html">Go back to A</a>.

Links in HTML don't go backwards. They always add a new history entry. For a Feathers UI app to feel native to the web, its navigation should feel similar to using links in HTML.

Additionally, consider that your routes are accessible as public URLs, which allows another website to link directly to any of your internal routes. If your view has a back button, and it should always go to a specific route in your app, that will only work if you use Push() because GoBack() could return anywhere, depending on how the user originally arrived at the route.

Regardless, RouterNavigator is capable of using a GoBack() action, if desired:

Route.withClass(ViewB.PATHNAME, ViewB, [
    Event.COMPLETE => GoBack()
]);

Just be careful how you use it.

Pass data between views

🚧 Data passing will be supported, but it has not been completely implemented yet.

Related Links

  • feathers.controls.navigators.RouterNavigator API Documentation
  • HTML History API
Last updated on 6/24/2020
← RadioHScrollBar / VScrollBar →
  • The Basics
  • Navigation
    • Navigate with events
  • Pass data between views
  • Related Links
Feathers UI
Feathers UI
  • Downloads
  • Showcase
  • Testimonials
  • Buy a T-Shirt!
Haxe / OpenFL
  • Documentation
  • API Reference
  • Samples
  • GitHub
  • Issue Tracker
ActionScript / Starling
  • Documentation
  • API Reference
  • Samples
  • GitHub
  • Issue Tracker
Feathers SDK (Starling)
  • Documentation
  • GitHub
Community
  • Forum
  • Discord
  • Stack Overflow
News & Updates
  • Blog (RSS, Atom)
  • Twitter
Copyright © 2021 Bowler Hat LLC — Illustrations by unDraw.