Navigation Types

A mobile application is a set of views. In PhoneJS, a view is displayed within a particular layout - the HTML template that usually includes elements that are common for several views. For instance, a view can be displayed in a layout that includes a navbar, as a global navigation control, or a toolbar, to provide different actions for the view. Some views can be displayed in an empty layout - just to show certain data and return to the previous view. All these scenarios are considered when designing an application, and all the required layouts are added to the application. In this article, you will learn how to define a navigation strategy according to which the required layouts are applied when necessary, and how to use and customize the framework's predefined navigation strategies.

Navigation Strategy

Each layout HTML template is managed by a certain controller that renders the layout markup, inserts the required view inside, animates view transitions, etc. All layout controllers are contained in the application's layoutControllers list. When a view is navigated, the layout controller that is most appropriate to the current navigation context is found. To indicate the required circumstances for a particular layout controller so that it can be found at these circumstances, the controller should be added to the controller list in the following way.

JavaScript
DevExpress.framework.html.layoutControllers.push({
    platform: 'ios',
    phone: true,
    root: true,
    navigationType: 'myNavigation',
    controller: new MyLayoutController()
});

Here, the following fields can be specified to define the required circumstances for the given controller.

  • root
    Indicates whether or not the view to which the application navigates must be a root view (the view that is available from the global navigation).
  • navigationType
    Specifies in which navigation strategy this controller can be used.
  • Any field of the device object.
    Specifies in which device the controller can be used.

All the layout controllers that are registered with the same navigationType field value represent a navigation strategy of the application. The navigation strategy that should be used in the application is set using the navigationType configuration option of the HtmlApplication object.

JavaScript
window.MyApp = {};
$(function() {
    MyApp.app = new DevExpress.framework.html.HtmlApplication({
        navigationType: 'myNavigation',
        namespace: MyApp
    });
    //...
});

Predefined Navigation Types

PhoneJS comes with a set of predefined navigation strategies. For each navigation strategy, there is a set of predefined layouts - HTML templates that are accompanied by the the CSS classes and JavaScript controllers. The layout controllers are added to the application's controller list with specified circumstances, including the required navigation strategy. This means that you don't need to think about layouts for your views. You can only specify the required strategy using the application's navigationType configuration option and link the predefined layouts that are required by this strategy.

JavaScript
window.MyApp = {};
$(function() {
    MyApp.app = new DevExpress.framework.html.HtmlApplication({
        navigationType: 'navbar',
        namespace: MyApp
    });
    //...
});
HTML
<script type="text/javascript" src="layouts/NavBar/NavbarLayout.js"></script>
<link rel="stylesheet" type="text/css" href="layouts/NavBar/NavbarLayout.css" />
<link rel="dx-template" type="text/html" href="layouts/NavBar/NavbarLayout.html"/>

The following navigation types are available.

  • navbar
    Different strategies are introduced for different platforms.

  • slideOut
    All views are displayed in the Slideout layout on all platforms.

  • split
    Designed to be used on Windows 8 tablet devices. Root views are displayed in the Navbar layout. Other views are displayed in the Split layout.

  • simple
    All views are displayed in the Simple layout on all platforms.

Global Navigation

All the predefined navigation strategies, except for the Simple one, utilize the layouts that include a widget that represents global navigation. This widget provides access to the main views of the application - the root views. To specify which views must be accessible from global navigation, use the navigation configuration option of the HtmlApplciation object.

JavaScript
window.MyApp = {};
$(function() {
    MyApp.app = new DevExpress.framework.html.HtmlApplication({
        navigationType: "navbar",
        navigation: [
            {
            title: "Home",
            action: "#home",
            icon: "home"
            },
            {
            title: "About",
            action: "#about",
            icon: "info"
            }
        ],
        namespace: MyApp
    });
});

Override Navigation Strategy

You can modify the navigation strategy that is set for the application. If you need for a particular view to be displayed in a specific layout that is not used for this view by the current navigation strategy, handle the resolveLayoutController event of the HtmlApplication object. Set the layoutController field of the object passed as the event handler's parameter to an instance of the required layout controller.

JavaScript
window.AppNamespace = {};
$(function () {
    AppNamespace.myController = new myLayoutController({ layoutTemplateName: "myLayout" });
    DevExpress.framework.html.layoutControllers.push({
        navigationType: "myControllerNavigation",
        controller: AppNamespace.myController
    });        
    AppNamespace.app = new DevExpress.framework.html.HtmlApplication(
        {
            namespace: AppNamespace,
            navigationType: "navbar"
        }
    );
    AppNamespace.app.router.register(":view/:name", { view: "home", name: '' });
    AppNamespace.app.resolveLayoutController.add(function(args) {
        var viewName = args.viewInfo.viewName;
        if(viewName === "about") {
            args.layoutController = AppNamespace.myController;
        }
    });
    AppNamespace.app.navigate();
});

The layout controller that is assigned to the layoutController field of the event handler's parameter must be contained in the layoutControllers collection. In addition, this controller must be already initialized at this step so that the required templates (layout template and a template for a loading view) are prepared beforehand. So, add an instance of the layout controller to the layoutControllers collection before the HtmlApplication object is created. When handling the resolveLayoutController event, assign this instance of the layout controller to the layoutController field of the event handler's parameter object. This is demonstrated in the example above.

If a variable with an instance of the required layout controller is not accessible, find the controller instance within the application's collection of available controllers. This collection includes only the layout controller instances that are appropriate for the current device (platform and form). To access this collection, use the availableLayoutControllers field of the object passed as the resolveLayoutController event handler parameter. The following example demonstrates how to set the predefined EmptyLayoutController layout controller for the "about" view in an application with a custom 'myNavigation' navigation type. The EmptyLayoutController controller is registered for the 'empty' navigation type, which helps find this controller in the controller collection.

JavaScript
window.AppNamespace = {};
$(function () {        
    AppNamespace.app = new DevExpress.framework.html.HtmlApplication(
        {
            namespace: AppNamespace,
            navigationType: 'myNavigation'
        }
    );
    AppNamespace.app.router.register(":view/:name", { view: "home", name: '' });
    AppNamespace.app.resolveLayoutController.add(function(args) {
        var viewName = args.viewInfo.viewName;
        if(viewName === "about") {
            var result = $.grep(args.availableLayoutControllers, function (item, index) {
                return item.navigationType == 'empty';
            });
            result.length ? result[0].controller : null;
            args.layoutController = result;
        }
    });
    AppNamespace.app.navigate();
});