App Framework

Jump to Table of Contents

The YUI App Framework is a rollup of the App, Model, Model List, Router, and View components, combined to form a simple MVC-style framework for writing single-page JavaScript applications.

You can use these components separately or together to create anything from simple non-interactive views to rich applications with URL-based routing, data binding, and full client-server synchronization.

If you've used DocumentCloud's excellent Backbone.js framework, many of the classes and APIs provided by App Framework components will look familiar to you. There are important differences, though, and the App Framework takes full advantage of YUI's powerful component and event infrastructure under the hood.

Getting Started

To include the source files for App Framework and its dependencies, first load the YUI seed file if you haven't already loaded it.

<script src="http://yui.yahooapis.com/3.5.0/build/yui/yui-min.js"></script>

Next, create a new YUI instance for your application and populate it with the modules you need by specifying them as arguments to the YUI().use() method. YUI will automatically load any dependencies required by the modules you specify.

<script>
// Create a new YUI instance and populate it with the required modules.
YUI().use('app', function (Y) {
    // App Framework is available and ready for use. Add implementation
    // code here.
});
</script>

For more information on creating YUI instances and on the use() method, see the documentation for the YUI Global Object.

Components of the App Framework

The app module is a rollup module consisting of the following individual components. These components may also be used individually if you don't need all of them at the same time.

Component Module Description
App app-base

Provides a top-level application component which manages navigation and views. This gives you a foundation and structure on which to build your application; it combines robust URL navigation with powerful routing and flexible view management.

Model model

A lightweight Y.Attribute-based data model with APIs for getting, setting, validating, and syncing attribute values to a persistence layer or server, as well as events for notifying subscribers of model changes.

Model List model-list

An array-like ordered list of Y.Model instances with APIs for adding, removing, sorting, filtering, and performing other actions on models in the list. Acts as a bubble target for events fired by the models in the list.

Router router

Provides URL-based same-page routing using HTML5 history (pushState) or the location hash, depending on what the user's browser supports.

View view

Represents a piece of an application's user interface and is responsible for rendering content and handling DOM events. Views are commonly associated with Models or Model Lists and are re-rendered when they change, although this isn't required.

App Component

App is a high-level component that builds upon other components in the App Framework. The App component is composed of Router and View, and also the Pjax utility. This combination creates a solid foundation and structure on which to build your application. It connects together robust URL navigation with powerful routing and flexible view management.

The goal of the App component is to provide you a place to organize and connect together the parts of your application. App implements infrastructural pieces which are common to all apps — such as managing views and the navigation between pages — allowing you to focus on the specifics of your app.

App will enable you to seamlessly enhance the user experience and performance of traditional client/server apps. It enables you to create richer interactions without compromising standard browser behavior, URLs, or search engine craw-ability. The Routing Coordination with Server and Progressively-Enhanced Apps sections of this guide contain details and best practices on accomplishing this.

You can also use the App component to build client-only apps for when there is no server, or the server is not capable of routing and handling requests. There are drawbacks to client-only apps which you need to be aware of and fully understand their implications. Be sure to read the Client-Only Apps section which contains details on these drawbacks and best practices.

The remaining sections of this guide provide details on what you'll need to know to start working with the App component. Refer to the previous section for information about the other components of the App Framework.

Using App

Instantiating App

Creating an App instance couldn't be any simpler:

var app = new Y.App();

Two instantiable classes are provided by the app-base module: Y.App, and Y.App.Base. The difference between these is that Y.App.Base provides the basic app functionality and will remain pure; whereas Y.App (which extends Y.App.Base) will have all of the app-component extensions automatically mixed-in when they are included in the YUI instance.

In the following example, we are including both the app-base and app-transitions modules. When the app-transitions module is added to the YUI instance it will automatically mix itself into the Y.App class, adding transitions to all Y.App instances, but Y.App.Base will remain unaffected by the inclusion of this module.

YUI().use('app-base', 'app-transitions', function (Y) {
    // This will create two YUI Apps, `basicApp` will not have transitions,
    // but `fancyApp` will have transitions support included and turn itself on.
    var basicApp = new Y.App.Base(),
        fancyApp = new Y.App({transitions: true});
});

While App instances are usable without any configuration, any non-trivial app will need to be configured. You might also want to extend Y.App by mixing-in additional functionality, or even create a custom App class to implement the specific features of your application. The Extending Y.App section explains how to do this.

Config Properties

When constructing a new Y.App instance you can provide a config object with initial values for attributes along with values for Y.View's properties and Y.Base's "special" properties (used only during initialization). In addition to these, the following non-attribute properties have specific initialization logic applied and can be passed to the Y.App constructor:

views

Hash of view-name to metadata used to declaratively describe an application's views and their relationship with the app and its other views. The views specified here will override any defaults provided by the views object on the prototype. Every Y.App instance gets its own copy of a views object so this object on the prototype will not be polluted.

See the App Properties and Declaring Views sections for more details.

Here's an example that defines some views at instantiation time:

var app = new Y.App({
    views: {
        home : {preserve: true},
        users: {preserve: true},
        user : {parent: 'users'}
    }
});

App Properties

The following properties are meaningful to App classes and subclasses. In addition to these, View's properties are also applicable Y.View is part of App's composition.

Property Default Value Description
views {}

Hash of view-name to metadata used to declaratively describe an application's views and their relationship with the app and its other views. See Declaring Views for more details.

The view metadata is composed of Objects keyed to a view-name that can have any or all of the following properties:

type

Function or a string representing the view constructor to use to create view instances. If a string is used, the constructor function is assumed to be on the Y object; e.g. "SomeView" -> Y.SomeView.

preserve

Boolean for whether the view instance should be retained. By default, the view instance will be destroyed when it is no longer the activeView. If true the view instance will simply be removed() from the DOM when it is no longer active. This is useful when the view is frequently used and may be expensive to re-create.

parent

String to another named view in this hash that represents the parent view within the application's view hierarchy; e.g. a "photo" view could have "album" has its parent view. This parent/child relationship is a useful cue for things like transitions.

instance

Used internally to manage the current instance of this named view. This can be used if your view instance is created up-front, or if you would rather manage the View lifecycle, but you probably should just let this be handled for you.

transitions {}

Default transitions to use when the activeView changes. See the Switching the Active View and Y.App.Transitions sections for more details.

The following are types of changes for which transitions can be defined that correspond to the relationship between the new and old activeView:

navigate

The default transition to use when changing the activeView of the application. This will be "fade" by default.

toChild

The transition to use when the new activeView is configured as a child of the previously active view via its parent property as defined in this app's views. This will be "slideLeft" by default.

toParent

The transition to use when the new activeView is configured as the parent of the previously active view as defined in this app's views. This will be "slideRight" by default.

The App class uses both properties and attributes. Properties are best when their stored data might be useful to multiple App instances, whereas attributes are best when the data being stored only pertains to a single instance.

App Attributes

App is composed of View, Router, and Pjax, all of which provide attributes that will be of interest to you — beyond these, App adds the following attributes:

Attribute Default Value Description
activeView null

The application's active/visible view. This attribute is read-only, to set the activeView use the showView() method.

See Switching the Active View for more details.

serverRouting undefined

Whether or not this application's server is capable of properly routing all requests and rendering the initial state in the HTML responses.

This can have three different values, each having particular implications on how the app will handle routing and navigation:

undefined

The best form of URLs will be chosen based on the capabilities of the browser. Given no information about the server environment, a balanced approach to routing and navigation is chosen. See Routing Coordination with Server for more details.

true

The server is fully capable of properly handling requests to all full-path URLs the app can produce.

This is the best option for progressive-enhancement because it will cause all URLs to always have full-paths, which means the server will be able to accurately handle all URLs this app produces. See Progressively-Enhanced Apps and Routing Coordination with Server for more details.

false

The server is not capable of properly handling requests to all full-path URLs the app can produce, therefore all routing will be handled by this App instance.

Be aware that this will cause all URLs to always be hash-based, even in browsers that are capable of using HTML5 history. Please make sure you fully understand the implications of client-only apps. See Client-Only Apps and Routing Coordination with Server for more details.

transitions false

Whether or not this application should use view transitions, and if so then which ones or true for the defaults which are specified by the transitions prototype property.

Note: Transitions are an opt-in feature and will only be used in browsers which support native CSS3 transitions.

See the Switching the Active View and Y.App.Transitions sections for more details.

viewContainer <div> Node

The node into which this app's views will be rendered when they become the activeView.

The view container node serves as the container to hold the app's activeView. Each time the activeView is set via showView(), the previous view will be removed from this node, and the new active view's container node will be appended.

The default view container is a <div> Node, but you can override this in a subclass, or by passing in a custom viewContainer config value at instantiation time. The viewContainer may be provided as a selector string, DOM element, or a Y.Node instance (having the viewContainer and the container be the same node is also supported).

The app's render() method will stamp the view container with the CSS class "yui3-app-views" and append it to the app's container node if it isn't already, and any activeView will be appended to this node if it isn't already.

See Rendering an App for more details.

A few of App's inherited attributes are given new default values:

Attribute Inherited From New Default Value Reason
container Y.View <body> Node

Apps are considered to be full-page by default.

html5 Y.Router auto

This value is dependent on the value of serverRouting and will default accordingly.

linkSelector Y.PjaxBase "a"

By default this selector should match all links on the page because full-page apps are the default.

Extending Y.App

The Y.App class is intended to be mutable insofar as being the host for all App-component features, whereas Y.App.Base is intended to remain pure and just host the basic set of features. This allows for two different ways to extend the functionality of Y.App: mixing-in features, and subclassing.

Mixing-In Features

Additional class extensions can be automatically mixed-into Y.App, doing so will dynamically extend the functionality of the App class making these new features available to all of its instances and subclasses. The Y.App.Transitions class extension, provided by the app-transitions module, uses this pattern to add transitions support to Y.App.

// Creates the namespace for the transitions class extension and assigns a
// simple constructor function to it.
Y.App.Transitions = function () {};

// This defines the prototype of the transitions class extension, the actual
// implementation has been left out for the sake of simplicity.
Y.App.Transitions.prototype = {

    // The implementation of the transition features would be here.

};

// Here the transitions class extension is being applied automatically by
// mixing itself into the `Y.App` class.
Y.Base.mix(Y.App, [Y.App.Transitions]);

When this module is included in the YUI instance, the transitions support for App can be used by simply toggling it on:

YUI().use('app-base', 'app-transitions', function (Y) {
    var app = new Y.App({transitions: true});
});

When writing your own class extensions to add features to Y.App, feel free to add them to App's namespace (e.g., Y.App.SomeNewFeature), and be sure to follow these two rules:

  1. The addition functionality should be disabled by default. The API for the class extensions should provide some way for the user to opt-in to using the features it adds.

    The Y.App.Transitions class extension does this be requiring a "truthy" value for the transitions property of the config object passed-in during instance creation.

  2. Be courteous to the other App component class extensions, since they all share the same prototype be careful not to unintentionally overwrite other properties or methods.

Subclassing

Creating class extensions for mixing-in features to Y.App is a great way to extend its functionality in a reusable way while not changing how you Instantiate an App; but might find it more useful to extend the Y.App class to create a subclass customized to your specific needs.

Use the Y.Base.create() method to extend Y.App and add or override prototype and static members and attributes. You may also optionally specify one or more class extensions to mix into your new class.

// Create a Y.CustomApp class that extends Y.App.
Y.CustomApp = Y.Base.create('customApp', Y.App, [], {
    // Add or override prototype properties and methods here.
}, {
    // Add static properties and methods here.

    ATTRS: {
        // Add or override default attributes here.
    }
});

One benefit of extending Y.App is that you can easily add default views, routes, and route handlers to your custom App class, and they'll be shared by all instances of that class unless overridden at the instance level:

// Create a Y.CustomApp class that extends Y.App.
Y.CustomApp = Y.Base.create('customApp', Y.App, [], {
    // Default registered views inherited by all CustomApp instances.
    views: {
        home : {preserve: true},
        users: {preserve: true},
        user : {parent: 'users'}
    },

    // Default route handlers inherited by all CustomApp instances.

    handleHome: function (req) {
        // Handle the "/" route here.
    },

    handleUsers: function (req) {
        // Handle the "/users/" route here.
    },

    handleUser: function (req) {
        // Handle the "/users/:name/" route here.
    }
}, {
    ATTRS: {
        // Share these routes with all CustomApp instances.
        routes: {
            value: [
                {path: '/',             callback: 'handleHome'},
                {path: '/users/',       callback: 'handleUsers'}
                {path: '/users/:name/', callback: 'handleUser'}
            ]
        }
    }
});

// Create a CustomApp instance that inherits the defaults and adds to them.
var app = new Y.CustomApp({
    // Register an additional view. The `home`, `users`, and `user` views will
    // also be inherited.
    views: {
        about: {preserve: true}
    }
});

// Add a route and route handler.
app.route('/about/', function (req) {
    // Handle the "/about/" route here.
});

Now all instances of Y.CustomApp will inherit all the custom defaults and can add to or override them. The app instance created here will handle the "/", "/users/", and "/users/:name/" routes in addition to its own "/about/" route.

Before you subclass Y.App, you should refer to App's API docs to become familiar with its public and protected properties and methods.

Routing Coordination with Server

Rendering an App

App inherits both its container attribute and render() method from View. Unlike View's empty render() implementation, App provides a default implementation which appends the activeView (if there is one) to the viewContainer node which itself is appended to the container node.

The basic usage of your app's render() method is to call it at least once, usually after you instantiate your app, this ensures the proper DOM structure is setup to handle rendering the app's views.

var app = new Y.App();
app.render();

This results in the HTML of the page looking like this:

<body class="yui3-app">
    ...
    <div class="yui3-app-views"></div>
</body>

By default, an app's container node will be the <body> element and its viewContainer node will be a new <div>.

Note: The "yui3-app" and "yui3-app-views" CSS classes are added to the container and viewContainer respectively — this happens when the app is rendered.

Specifying Container Nodes

When constructing a new App instance you can specify values for the app's container and viewContainer attributes, and they can even reference the same node.

var app = new Y.App({
    container    : '#wrapper',
    viewContainer: '#wrapper'
});

app.render();

Assuming that a <div id="wrapper"> node already exists on the page, this uses a CSS selector string to reference the node, assigns it to both containers, and results in the following HTML:

<div id="wrapper" class="yui3-app yui3-app-views">
    ...
</div>

If you specify a container that is not already within the markup of the page, you'll need to manually append it to an element that is:

var app = new Y.App({
    container: Y.Node.create('<div id="fancy-app" />')
});

app.render().get('container').appendTo('body');

This results in the HTML of the page looking like this:

<body>
    ...
    <div id="fancy-app" class="yui3-app">
        <div class="yui3-app-views"></div>
    </div>
</body>

Refer to App's API Docs for more details about container and viewContainer attributes.

Overriding render()

You may override the render() method to customize how the app renders itself, particularly if you are creating an App subclass.

Note: You should expect that the viewContainer's contents will be modified by the app for the purpose of rendering the activeView when it changes; and ideally your render() method should also return this at the end to allow chaining, but that's up to you.

The following provides a templates for how you could subclass Y.App and implement a custom render() method while still preserving its default behavior:

Y.CustomApp = Y.Base.create('customApp', Y.App, [], {
    render: function () {
        // This calls the superclass' (Y.App) implementation of the `render()`
        // method to preserve the default behavior.
        Y.CustomApp.superclass.render.apply(this, arguments);

        // Provide your custom rendering logic here.

        // Returns this `Y.CustomApp` instance to allow for chaining.
        return this;
    }
});

Refer to App's API Docs for more details about the render() method.

View Management

A primary feature of App is its flexible view management, which enables you to declare the primary views of your application and easily switch which one is active. This is very handy for defining your app's top-level "page" views, then switching between them as a user navigates through the application.

Declaring Views

The views property of an App class allows you to specify a mapping of view-names to view-metadata that should be registered to your app. This way you can specify information about your app's views — how they should be treated by the app, and how they related to other views — up-front, in a declarative way that is self-documenting.

You can setup this views mapping on both App subclasses and instances. Every App instance will receive its own copy of a views object, any views metadata defined at the class-level will be used as defaults and merged with any views specified during instantiation time.

The follow example shows the creation of an App subclass, CustomApp, which has a few default views defined, and an instance of CustomApp which defines another view and overrides some of the defaults.

// Create a Y.CustomApp class that extends Y.App.
Y.CustomApp = Y.Base.create('customApp', Y.App, [], {
    // Default registered views inherited by all CustomApp instances.
    views: {
        home : {preserve: true},
        users: {preserve: true},
        user : {parent: 'users'}
    }
});

// Create a CustomApp instance that inherits the defaults and adds to them.
var app = new Y.CustomApp({
    // Additional view metadata to be merged with the defaults.
    views: {
        home : {preserve: false},
        user : {preserve: false},
        about: {preserve: true}
    }
});

Using the getViewInfo() method, we can see how the views metadata from our CustomView class and instance were merged together.

// Overwrote "home"'s default `preserve` value.
Y.log(app.getViewInfo('home').preserve);  // => false

// Added `preserve` to "user" view,
// and this did not overwrite the default `parent` value.
Y.log(app.getViewInfo('user').parent);    // => "home"
Y.log(app.getViewInfo('user').preserve);  // => false

// The specified "about" view was registered.
Y.log(app.getViewInfo('about').preserve); // => true

See the App Properties section above for more details on what metadata can be stored for each view in views mapping.

Switching the Active View

When decomposing an application into discrete user-interfaces, it is natural to think of these as different "pages"—with each one serving a particular role and being the main content on the screen. With the App component, changing the main content/user-interface is done by updating an app's activeView attribute via the showView() method.

Working in concert with an app's registered views, the showView() method will take a specified view and make it the app's activeView. This view will be "attached" to the app by rendering it inside the app's viewContainer and any custom events fired by the view will bubble to the app. Any previously active view will be "detached" from the app, removed from the DOM, and either preserved for later use or properly destroyed.

The following example is the most basic "Hello World" app:

// Creates a new App and View instance.
var app  = new Y.App(),
    view = new Y.View();

// Overrides the view's `render()` method to render text into its `container`.
view.render = function () {
    this.get('container').set('text', 'Hello World!');
    return this;
};

// Renders the `app` and `view`, then sets the view as the app's `activeView`.
app.render().showView(view.render());

// Verify that `view` is now the `activeView`, and that the view's `container`
// is now rendered within the app's `viewContainer`.
Y.log(app.get('activeView') === view);                           // => true
Y.log(app.get('viewContainer').contains(view.get('container'))); // => true

This results in the HTML of the page looking like this:

<body class="yui3-app">
    ...
    <div class="yui3-app-views">
        <div>Hello World!</div>
    </div>
</body>

This example app can easily become dynamic and have the ability to say hello to someone by name. By creating a reusable HelloView class the app can dynamically switch between outputting "Hello World!" and "Hello [name]!" where the "name" is a path segment in the URL.

// Creates a HelloView which can say hello to someone named, or to the World
// if a name is not specified.
Y.HelloView = Y.Base.create('helloView', Y.View, [], {
    render: function () {
        var name = this.get('name');
        this.get('container').set('text', 'Hello ' + (name || 'World') + '!');
        return this;
    }
});

// Creates a new App instance and registers the HelloView.
var app = new Y.App({
    views: {
        hello: {type: 'HelloView'}
    }
});

// Adds a route handler for "/" to show the HelloView.
app.route('/', function (req) {
    // Sets the `activeView` to a new instance of a `Y.HelloView` by just
    // passing "hello", the name of the registered view.
    this.showView('hello');
});

// Adds a route handler for "/:name" to show the HelloView with a `name`.
app.route('/:name', function (req) {
    // The name which we want to say hello to is specified on `req.params`.
    var name = req.params.name;
    // Sets the `activeView` to a new instance of a `Y.HelloView`, but here
    // we are also passing a config object which the new view instance will
    // be constructed with, and it contains the name which we'll say hello to.
    this.showView('hello', {name: name});
});

// Renders the app, then saves a new history entry for "/eric" which will
// dispatch the "/:name" route handler.
app.render().save('/eric');

This results in the URL being updated to either "/eric" or "/#/eric" depending on whether the browser is capable of HTML5 history, and the HTML of the page looking like this:

<body class="yui3-app">
    ...
    <div class="yui3-app-views">
        <div>Hello eric!</div>
    </div>
</body>

Refer to App's API docs for more details about the showView() method.

A key feature of Y.App is its powerful navigation management. You can simply use standard HTML links within your app and when the user clicks a link, Y.App will handle it if there’s a matching route for that URL. With the navigation-related config options you have full control over your app's navigation behavior and experience, plus your app will automatically use the best available navigation method based on these settings, the browser’s capabilities, and the actions of the user.

This enables an app fulfill a "page request" by using data it already has stored in models or loading new data, then composing and showing a view which represents the app's current state for this URL — all without requiring a full page load.

Programmatic navigation

Beyond handling navigation via link clicks, Y.App also exposes a programmatic way to navigate the user though your app via the navigate() method.

App's navigate() method implements a higher level concept of "browsing" over the save() and replace() methods. It will manage a user's navigation history like a browser, and is the recommended method to use when programmatically navigating the user to URLs within your app.

The navigate() method will do the right thing (what the browser would do) when navigating the user to the same URL they are currently on — it will replace the history entry — or to an in-page fragment identifier — which only when configured will navigate. The following demonstrates some of these behaviors:

var app = new Y.App();

app.route('*', function (req, res, next) {
    // Handle all URLs.
});

// Save a new history entry for "/", or replaces the current entry if we're
// already on "/".
app.navigate('/'); // => true

// Does not navigate even though there's a matching route handler.
app.navigate('#top'); // => false

// Enable navigation on hash-only changes to the URL.
app.set('navigateOnHash', true);

// Does navigate because `navigateOnHash` was enabled.
app.navigate('#top'); // => true

Refer to App's API Docs for more details about the navigate() method.

Configuring Navigation Behavior

The navigation features of Y.App are built on the base pjax functionality. This is what enables users to navigate to the different sections or "pages" of an app while avoiding full page loads.

The following are configuration attributes which define an app’s navigation behavior:

Attribute Defined in Default Value Description
linkSelector Y.PjaxBase "a"

CSS selector string used to filter link click events so that only the links which match it will have the enhanced-navigation behavior of pjax applied.

When a link is clicked and that link matches this selector, navigating to the link's href URL using the enhanced, pjax, behavior will be attempted; and the browser's default way to navigate to new pages will be the fallback.

By default this selector will match all links on the page.

navigateOnHash Y.PjaxBase false

Whether navigating to a hash-fragment identifier on the current page should be enhanced and cause the navigate event to fire.

By default Pjax allows the browser to perform its default action when a user is navigating within a page by clicking in-page links (e.g. <a href="#top">Top of page</a>) and does not attempt to interfere or enhance in-page navigation.

scrollToTop Y.PjaxBase true

Whether the page should be scrolled to the top after navigating to a URL.

When the user clicks the browser's back button, the previous scroll position will be maintained.

serverRouting Y.App.Base undefined

Whether or not this application's server is capable of properly routing all requests and rendering the initial state in the HTML responses.

See App Attributes and Routing Coordination with Server for more details.

When the user is navigating to a URL for which the app has a route handler, the navigate event will fire. The default action of this event updates the browser’s address bar to reflect the new URL, causing the app to dispatch to the matching route handlers.

Listening to your app's navigate event is a useful way to indicate to the user that something is loading while they wait for the app to fully handle the new URL, possibly loading data from a remote server.

var app = new Y.App({
    views: {
        users: {}
    },

    users: new Y.ModelList()
});

app.route('/users/', function () {
    var users = app.get('users');

    // Load users data from a remote server.
    users.load(function () {
        app.showView('users', {users: users});

        // Removes the "loading" class from the app's `container` node.
        app.get('container').removeClass('loading');
    });
});

// Listen for the app's `navigate` event.
app.on('navigate', function (e) {
    // Adds the "loading" class to the app's `container` node.
    app.get('container').addClass('loading');
});

// Navigate the user to "/users/".
app.navigate('/users/');

Refer to App's API Docs for more details about the navigate event.

Best Practices

Progressively-Enhanced Apps

Client-Only Apps

App Extensions

Y.App.Transitions

The Transitions extension provides view transitions for apps in browsers which support native CSS3 transitions. View transitions visually enhance the change from one "page" to the next that is both pleasant to the user and helps to communicate a hierarchy between sections of an application.

Enabling Transitions

Enabling transitions for an app just requires opting-in. The following will create a new Y.App instance with the default transitions enabled:

var app = new Y.App({transitions: true});

With transitions enabled for an app, anytime the app's activeView changes, there will be a visual transition from the old to the new active view. How an app's views are configured effects which transition will be used, e.g. when changing between views which have a hierarchical relationship a sliding transition will be used.

Types of activeView Changes

The following are the types of activeView changes for which transitions can be defined that correspond to the relationship between the new and old activeView:

navigate

The default transition to use when changing the activeView of the application. This will be "fade" by default.

toChild

The transition to use when the new activeView is configured as a child of the previously active view via its parent property as defined in this app's views. This will be "slideLeft" by default.

toParent

The transition to use when the new activeView is configured as the parent of the previously active view as defined in this app's views. This will be "slideRight" by default.

Overriding Default Transitions

The default transitions can be overridden in the following ways:

The following example will override which transitions should be used by default, and specifically set the transition option on certain calls to showView().

var app = new Y.App({
    // The app's three views and their relationships between one another.
    views: {
        home   : {},
        about  : {},
        contact: {parent: 'about'},
        team   : {parent: 'about'}
    },

    // Overrides the default transitions types all to "fade" which will
    // cross-fade between `activeView` changes.
    transitions: {
        navigate: 'fade',
        toChild : 'fade',
        toParent: 'fade'
    },

    // The app's `team` model list for use by the "team" view.
    team: new Y.ModelList().reset([
        {name: 'Eric Ferraiuolo'},
        {name: 'Ryan Grove'}
    ])
});

app.route('/', function () {
    // Will transition via "fade".
    app.showView('home');
});

app.route('/about/', function () {
    // Will transition via "fade", even though we maybe coming from a child
    // view (i.e. "contact" or "team").
    app.showView('about');
});

app.route('/about/contact/', function () {
    // Will transition via "fade", even though we maybe coming from the parent
    // "about" view.
    app.showView('contact');
});

app.route('/about/team/', function () {
    // Shows the "team" view, passing it the app's `team` model list, and
    // overrides the `transition` options so no visual transitions will occur.
    app.showView('team', {team: this.get('team')}, {transition: false});
});

app.render().dispatch();

Transition-Aiding CSS

Some structural CSS is required to setup an app's container and viewContainer nodes so the app's views transition properly. While an app's views are transitioning, the CSS class: yui3-app-transitioning will be added to the app's container node.

Note: While transitioning, the app's viewContainer node will have its overflow-x set to hidden. This causes its margins to not collapse with its child nodes. To compensate for this, it is best to not style your views with margins.

Apps vs. Widgets