Skip to content

Frequently Asked Questions

Nate Abele edited this page Jul 16, 2013 · 94 revisions

How to: Configure ui-router from multiple modules

How do I configure ui-router from multiple modules, it doesn't seem to get the same state provider?

What often goes wrong is dependencies. E.g:

angular.module('application', [...]).config(function ($stateProvider) {
    $stateProvider
        .state("feature1", { url : '/Feature1'...})
        .state("feature2", { url : '/Feature2'...});
});
angular.module('feature1', ['application', ...]).config(function ($stateProvider) {
    $stateProvider
        .state("feature1.home", {...})
        .state("feature1.detail", {...});
});

Example: http://plnkr.co/edit/WSmPX7JITGOsZ07L1UQP?p=preview

Note: Remember only to declare dependencies once on module creation, so if you make several calls to angular.module for the same module, only the first should define dependencies.

How To: Open a dialog/modal at a certain state

How do I tell ui-router that I'd like a certain state to open a dialog or modal instead of swapping out ui-view templates?

Here's an example of to do it using ui-bootstrap's $dialog service. This example only specifies an onEnter function. There is no template, controller, etc. So essentially the dialog is shown, then when its closed it returns to the items state. You are still responsible for handling what state your app transitions to when the dialog closes.

$stateProvider.state("items.add", {
    url: "/add",
    onEnter: function($stateParams, $state, $dialog, $resource) {

        var Item = $resource(...);

        $dialog.dialog({
            keyboard: true,
            templateUrl: "items/add",
            backdropClick: false,
            dialogFade: true,
            controller: ['$scope', function($scope) {

                angular.extend($scope, {
                    title: "Create new item",
                    button: "Add",
                    campaign: new Item(),
                    $stateParams: $stateParams,
                    $state: $state,
                    save: function() {
                        var self = $scope;

                        this.item.$save(function() {
                            self.$emit('items.refresh');
                            $state.transitionTo('items');
                        });
                    }
                });
            }]
        }).open().then(function(result) {
            if (!result) {
                return $state.transitionTo("items");
            }
        });
    }
});

How to: Animate ui-view with ng-animate

How do I add animation effects to the ui-view templates that are loaded?

Make sure you are using the latest unstable version of angular (1.1.5 as of writing this, 1.1.4 had a totally different syntax that won't work with this example).

Add ng-animate="'view'" to your ui-view:

<div ui-view ng-animate="'view'"></div> 

The animation class doesn't have to be "view" that's just an example. Then create a view-enter, view-enter-active, view-leave, and view-leave-active class styles in your css. The "-enter" class will be used to set up the animations and the "-enter-active" will be used as the end point of the animation.

Here is a plunkr to show you: http://plnkr.co/edit/EmNvz8?p=preview

How to: Configure your server to work with html5Mode

When I add $locationProvider.html5Mode(true), my site will not allow pasting of urls. How do I configure my server to work when html5Mode is true?

Warning: If you have server side rewrites already set up and still experience issues, please see Issue: assets and templates are not loading.

When you have html5Mode enabled, the # character will no longer be used in your urls. The # symbol is useful because it requires no server side configuration. Without #, the url looks much nicer, but it also requires server side rewrites. Here are some examples:

Apache Rewrites

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

Express Rewrites

var express = require('express');
var app = express();

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));

app.all('/*', function(req, res, next) {
    // Just send the index.html for other files to support HTML5Mode
    res.sendfile('index.html', { root: __dirname });
});

app.listen(3006); //the port you want to use

Issue: My assets and templates are not loading

This may be related to a nasty issue where assets and templates are not loading. It showed up during Angular 1.1.5 and is a bug in the core library.

A solution that has worked for many is to add the following tag to your index.html head:

<head>
    ...
    <base href="/"></base>
    ...
 </head>

... if your application is running at the root of your domain.

... and if your application is running in a subdirectory, specify that subdirectory (e.g. 'myapp'):

<head>
    ...
    <base href="/myapp/"></base>
    ...
 </head>

Bugs that were solved by this solution: 89, 200, 208, 250, SO 17200231

Other Resources: