diff --git a/sample/app/app.js b/sample/app/app.js
new file mode 100644
index 000000000..eacc40127
--- /dev/null
+++ b/sample/app/app.js
@@ -0,0 +1,96 @@
+// Make sure to include the `ui.router` module as a dependency
+angular.module('uiRouterSample', [
+ 'uiRouterSample.contacts',
+ 'uiRouterSample.contacts.service',
+ 'uiRouterSample.utils.service',
+ 'ui.router',
+ 'ngAnimate'
+])
+
+.run(
+ [ '$rootScope', '$state', '$stateParams',
+ function ($rootScope, $state, $stateParams) {
+
+ // It's very handy to add references to $state and $stateParams to the $rootScope
+ // so that you can access them from any scope within your applications.For example,
+ //
will set the
// to active whenever
+ // 'contacts.list' or one of its decendents is active.
+ $rootScope.$state = $state;
+ $rootScope.$stateParams = $stateParams;
+ }
+ ]
+)
+
+.config(
+ [ '$stateProvider', '$urlRouterProvider',
+ function ($stateProvider, $urlRouterProvider) {
+
+ /////////////////////////////
+ // Redirects and Otherwise //
+ /////////////////////////////
+
+ // Use $urlRouterProvider to configure any redirects (when) and invalid urls (otherwise).
+ $urlRouterProvider
+
+ // The `when` method says if the url is ever the 1st param, then redirect to the 2nd param
+ // Here we are just setting up some convenience urls.
+ .when('/c?id', '/contacts/:id')
+ .when('/user/:id', '/contacts/:id')
+
+ // If the url is ever invalid, e.g. '/asdf', then redirect to '/' aka the home state
+ .otherwise('/');
+
+
+ //////////////////////////
+ // State Configurations //
+ //////////////////////////
+
+ // Use $stateProvider to configure your states.
+ $stateProvider
+
+ //////////
+ // Home //
+ //////////
+
+ .state("home", {
+
+ // Use a url of "/" to set a states as the "index".
+ url: "/",
+
+ // Example of an inline template string. By default, templates
+ // will populate the ui-view within the parent state's template.
+ // For top level states, like this one, the parent template is
+ // the index.html file. So this template will be inserted into the
+ // ui-view within index.html.
+ template: '
Welcome to the UI-Router Demo
' +
+ '
Use the menu above to navigate. ' +
+ 'Pay attention to the $state and $stateParams values below.
' +
+ '
Click these links—Alice or ' +
+ 'Bob—to see a url redirect in action.
'
+
+ })
+
+ ///////////
+ // About //
+ ///////////
+
+ .state('about', {
+ url: '/about',
+
+ // Showing off how you could return a promise from templateProvider
+ templateProvider: ['$timeout',
+ function ( $timeout) {
+ return $timeout(function () {
+ return '
';
+ }, 100);
+ }]
+ })
+ }
+ ]
+);
diff --git a/sample/app/contacts/contacts-service.js b/sample/app/contacts/contacts-service.js
new file mode 100644
index 000000000..7125d93c2
--- /dev/null
+++ b/sample/app/contacts/contacts-service.js
@@ -0,0 +1,22 @@
+angular.module('uiRouterSample.contacts.service', [
+
+])
+
+// A RESTful factory for retreiving contacts from 'contacts.json'
+.factory('contacts', ['$http', function ($http, utils) {
+ var path = 'assets/contacts.json';
+ var contacts = $http.get(path).then(function (resp) {
+ return resp.data.contacts;
+ });
+
+ var factory = {};
+ factory.all = function () {
+ return contacts;
+ };
+ factory.get = function (id) {
+ return contacts.then(function(){
+ return utils.findById(contacts, id);
+ })
+ };
+ return factory;
+}]);
\ No newline at end of file
diff --git a/sample/contacts.detail.html b/sample/app/contacts/contacts.detail.html
similarity index 100%
rename from sample/contacts.detail.html
rename to sample/app/contacts/contacts.detail.html
diff --git a/sample/contacts.detail.item.edit.html b/sample/app/contacts/contacts.detail.item.edit.html
similarity index 100%
rename from sample/contacts.detail.item.edit.html
rename to sample/app/contacts/contacts.detail.item.edit.html
diff --git a/sample/contacts.detail.item.html b/sample/app/contacts/contacts.detail.item.html
similarity index 100%
rename from sample/contacts.detail.item.html
rename to sample/app/contacts/contacts.detail.item.html
diff --git a/sample/contacts.html b/sample/app/contacts/contacts.html
similarity index 100%
rename from sample/contacts.html
rename to sample/app/contacts/contacts.html
diff --git a/sample/app/contacts/contacts.js b/sample/app/contacts/contacts.js
new file mode 100644
index 000000000..6414f578a
--- /dev/null
+++ b/sample/app/contacts/contacts.js
@@ -0,0 +1,206 @@
+angular.module('uiRouterSample.contacts', [
+ 'ui.router'
+])
+
+.config(
+ [ '$stateProvider', '$urlRouterProvider',
+ function ($stateProvider, $urlRouterProvider) {
+ $stateProvider
+ //////////////
+ // Contacts //
+ //////////////
+ .state('contacts', {
+
+ // With abstract set to true, that means this state can not be explicitly activated.
+ // It can only be implicitly activated by activating one of it's children.
+ abstract: true,
+
+ // This abstract state will prepend '/contacts' onto the urls of all its children.
+ url: '/contacts',
+
+ // Example of loading a template from a file. This is also a top level state,
+ // so this template file will be loaded and then inserted into the ui-view
+ // within index.html.
+ templateUrl: 'app/contacts/contacts.html',
+
+ // Use `resolve` to resolve any asynchronous controller dependencies
+ // *before* the controller is instantiated. In this case, since contacts
+ // returns a promise, the controller will wait until contacts.all() is
+ // resolved before instantiation. Non-promise return values are considered
+ // to be resolved immediately.
+ resolve: {
+ contacts: ['contacts',
+ function( contacts){
+ return contacts.all();
+ }]
+ },
+
+ // You can pair a controller to your template. There *must* be a template to pair with.
+ controller: ['$scope', '$state', 'contacts', 'utils',
+ function ( $scope, $state, contacts, utils) {
+
+ // Add a 'contacts' field in this abstract parent's scope, so that all
+ // child state views can access it in their scopes. Please note: scope
+ // inheritance is not due to nesting of states, but rather choosing to
+ // nest the templates of those states. It's normal scope inheritance.
+ $scope.contacts = contacts;
+
+ $scope.goToRandom = function () {
+ var randId = utils.newRandomKey($scope.contacts, "id", $state.params.contactId);
+
+ // $state.go() can be used as a high level convenience method
+ // for activating a state programmatically.
+ $state.go('contacts.detail', { contactId: randId });
+ };
+ }]
+ })
+
+ /////////////////////
+ // Contacts > List //
+ /////////////////////
+
+ // Using a '.' within a state name declares a child within a parent.
+ // So you have a new state 'list' within the parent 'contacts' state.
+ .state('contacts.list', {
+
+ // Using an empty url means that this child state will become active
+ // when its parent's url is navigated to. Urls of child states are
+ // automatically appended to the urls of their parent. So this state's
+ // url is '/contacts' (because '/contacts' + '').
+ url: '',
+
+ // IMPORTANT: Now we have a state that is not a top level state. Its
+ // template will be inserted into the ui-view within this state's
+ // parent's template; so the ui-view within contacts.html. This is the
+ // most important thing to remember about templates.
+ templateUrl: 'app/contacts/contacts.list.html'
+ })
+
+ ///////////////////////
+ // Contacts > Detail //
+ ///////////////////////
+
+ // You can have unlimited children within a state. Here is a second child
+ // state within the 'contacts' parent state.
+ .state('contacts.detail', {
+
+ // Urls can have parameters. They can be specified like :param or {param}.
+ // If {} is used, then you can also specify a regex pattern that the param
+ // must match. The regex is written after a colon (:). Note: Don't use capture
+ // groups in your regex patterns, because the whole regex is wrapped again
+ // behind the scenes. Our pattern below will only match numbers with a length
+ // between 1 and 4.
+
+ // Since this state is also a child of 'contacts' its url is appended as well.
+ // So its url will end up being '/contacts/{contactId:[0-9]{1,8}}'. When the
+ // url becomes something like '/contacts/42' then this state becomes active
+ // and the $stateParams object becomes { contactId: 42 }.
+ url: '/{contactId:[0-9]{1,4}}',
+
+ // If there is more than a single ui-view in the parent template, or you would
+ // like to target a ui-view from even higher up the state tree, you can use the
+ // views object to configure multiple views. Each view can get its own template,
+ // controller, and resolve data.
+
+ // View names can be relative or absolute. Relative view names do not use an '@'
+ // symbol. They always refer to views within this state's parent template.
+ // Absolute view names use a '@' symbol to distinguish the view and the state.
+ // So 'foo@bar' means the ui-view named 'foo' within the 'bar' state's template.
+ views: {
+
+ // So this one is targeting the unnamed view within the parent state's template.
+ '': {
+ templateUrl: 'app/contacts/contacts.detail.html',
+ controller: ['$scope', '$stateParams', 'utils',
+ function ( $scope, $stateParams, utils) {
+ $scope.contact = utils.findById($scope.contacts, $stateParams.contactId);
+ }]
+ },
+
+ // This one is targeting the ui-view="hint" within the unnamed root, aka index.html.
+ // This shows off how you could populate *any* view within *any* ancestor state.
+ 'hint@': {
+ template: 'This is contacts.detail populating the "hint" ui-view'
+ },
+
+ // This one is targeting the ui-view="menu" within the parent state's template.
+ 'menuTip': {
+ // templateProvider is the final method for supplying a template.
+ // There is: template, templateUrl, and templateProvider.
+ templateProvider: ['$stateParams',
+ function ( $stateParams) {
+ // This is just to demonstrate that $stateParams injection works for templateProvider.
+ // $stateParams are the parameters for the new state we're transitioning to, even
+ // though the global '$stateParams' has not been updated yet.
+ return 'Contact ID: ' + $stateParams.contactId + '';
+ }]
+ }
+ }
+ })
+
+ //////////////////////////////
+ // Contacts > Detail > Item //
+ //////////////////////////////
+
+ .state('contacts.detail.item', {
+
+ // So following what we've learned, this state's full url will end up being
+ // '/contacts/{contactId}/item/:itemId'. We are using both types of parameters
+ // in the same url, but they behave identically.
+ url: '/item/:itemId',
+ views: {
+
+ // This is targeting the unnamed ui-view within the parent state 'contact.detail'
+ // We wouldn't have to do it this way if we didn't also want to set the 'hint' view below.
+ // We could instead just set templateUrl and controller outside of the view obj.
+ '': {
+ templateUrl: 'app/contacts/contacts.detail.item.html',
+ controller: ['$scope', '$stateParams', '$state', 'utils',
+ function ( $scope, $stateParams, $state, utils) {
+ $scope.item = utils.findById($scope.contact.items, $stateParams.itemId);
+
+ $scope.edit = function () {
+ // Here we show off go's ability to navigate to a relative state. Using '^' to go upwards
+ // and '.' to go down, you can navigate to any relative state (ancestor or descendant).
+ // Here we are going down to the child state 'edit' (full name of 'contacts.detail.item.edit')
+ $state.go('.edit', $stateParams);
+ };
+ }]
+ },
+
+ // Here we see we are overriding the template that was set by 'contact.detail'
+ 'hint@': {
+ template: ' This is contacts.detail.item overriding the "hint" ui-view'
+ }
+ }
+ })
+
+ /////////////////////////////////////
+ // Contacts > Detail > Item > Edit //
+ /////////////////////////////////////
+
+ // Notice that this state has no 'url'. States do not require a url. You can use them
+ // simply to organize your application into "places" where each "place" can configure
+ // only what it needs. The only way to get to this state is via $state.go (or transitionTo)
+ .state('contacts.detail.item.edit', {
+ views: {
+
+ // This is targeting the unnamed view within the 'contact.detail' state
+ // essentially swapping out the template that 'contact.detail.item' had
+ // had inserted with this state's template.
+ '@contacts.detail': {
+ templateUrl: 'app/contacts/contacts.detail.item.edit.html',
+ controller: ['$scope', '$stateParams', '$state', 'utils',
+ function ( $scope, $stateParams, $state, utils) {
+ $scope.item = utils.findById($scope.contact.items, $stateParams.itemId);
+ $scope.done = function () {
+ // Go back up. '^' means up one. '^.^' would be up twice, to the grandparent.
+ $state.go('^', $stateParams);
+ };
+ }]
+ }
+ }
+ });
+ }
+ ]
+);
\ No newline at end of file
diff --git a/sample/contacts.list.html b/sample/app/contacts/contacts.list.html
similarity index 100%
rename from sample/contacts.list.html
rename to sample/app/contacts/contacts.list.html
diff --git a/sample/contacts.json b/sample/assets/contacts.json
similarity index 100%
rename from sample/contacts.json
rename to sample/assets/contacts.json
diff --git a/sample/common/utils/utils-service.js b/sample/common/utils/utils-service.js
new file mode 100644
index 000000000..9d1fdb5ff
--- /dev/null
+++ b/sample/common/utils/utils-service.js
@@ -0,0 +1,24 @@
+angular.module('uiRouterSample.utils.service', [
+
+])
+
+.factory('utils', function () {
+ return {
+ // Util for finding an object by its 'id' property among an array
+ findById: function findById(a, id) {
+ for (var i = 0; i < a.length; i++) {
+ if (a[i].id == id) return a[i];
+ }
+ return null;
+ },
+
+ // Util for returning a randomKey from a collection that also isn't the current key
+ newRandomKey: function newRandomKey(coll, key, currentKey){
+ var randKey;
+ do {
+ randKey = coll[Math.floor(coll.length * Math.random())][key];
+ } while (randKey == currentKey);
+ return randKey;
+ }
+ };
+});
\ No newline at end of file
diff --git a/sample/styles.css b/sample/css/styles.css
similarity index 100%
rename from sample/styles.css
rename to sample/css/styles.css
diff --git a/sample/factory.js b/sample/factory.js
deleted file mode 100644
index 02083584c..000000000
--- a/sample/factory.js
+++ /dev/null
@@ -1,45 +0,0 @@
-angular.module('uiRouterSample')
-
- // A RESTful factory for retreiving contacts from 'contacts.json'
- .factory('contacts', ['$http', function ($http, utils) {
- var path = 'contacts.json';
- var contacts = $http.get(path).then(function (resp) {
- return resp.data.contacts;
- });
-
- var factory = {};
- factory.all = function () {
- return contacts;
- };
- factory.get = function (id) {
- return contacts.then(function(){
- return utils.findById(contacts, id);
- })
- };
- return factory;
- }])
-
- .factory('utils', function () {
-
- return {
-
- // Util for finding an object by its 'id' property among an array
- findById: function findById(a, id) {
- for (var i = 0; i < a.length; i++) {
- if (a[i].id == id) return a[i];
- }
- return null;
- },
-
- // Util for returning a randomKey from a collection that also isn't the current key
- newRandomKey: function newRandomKey(coll, key, currentKey){
- var randKey;
- do {
- randKey = coll[Math.floor(coll.length * Math.random())][key];
- } while (randKey == currentKey);
- return randKey;
- }
-
- };
-
- });
\ No newline at end of file
diff --git a/sample/index.html b/sample/index.html
index 12e7a20cf..58de89a15 100644
--- a/sample/index.html
+++ b/sample/index.html
@@ -5,21 +5,30 @@
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
ui-router
diff --git a/sample/module.js b/sample/module.js
deleted file mode 100644
index 2c28748d6..000000000
--- a/sample/module.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Make sure to include the `ui.router` module as a dependency
-angular.module('uiRouterSample', ['ui.router', 'ngAnimate'])
- .run(
- [ '$rootScope', '$state', '$stateParams',
- function ($rootScope, $state, $stateParams) {
-
- // It's very handy to add references to $state and $stateParams to the $rootScope
- // so that you can access them from any scope within your applications.For example,
- //
will set the
// to active whenever
- // 'contacts.list' or one of its decendents is active.
- $rootScope.$state = $state;
- $rootScope.$stateParams = $stateParams;
- }]);
diff --git a/sample/states.js b/sample/states.js
deleted file mode 100644
index c7a669bc4..000000000
--- a/sample/states.js
+++ /dev/null
@@ -1,270 +0,0 @@
-// Make sure to include the `ui.router` module as a dependency.
-angular.module('uiRouterSample')
- .config(
- [ '$stateProvider', '$urlRouterProvider',
- function ($stateProvider, $urlRouterProvider) {
-
- /////////////////////////////
- // Redirects and Otherwise //
- /////////////////////////////
-
- // Use $urlRouterProvider to configure any redirects (when) and invalid urls (otherwise).
- $urlRouterProvider
-
- // The `when` method says if the url is ever the 1st param, then redirect to the 2nd param
- // Here we are just setting up some convenience urls.
- .when('/c?id', '/contacts/:id')
- .when('/user/:id', '/contacts/:id')
-
- // If the url is ever invalid, e.g. '/asdf', then redirect to '/' aka the home state
- .otherwise('/');
-
-
- //////////////////////////
- // State Configurations //
- //////////////////////////
-
- // Use $stateProvider to configure your states.
- $stateProvider
-
- //////////
- // Home //
- //////////
-
- .state("home", {
-
- // Use a url of "/" to set a states as the "index".
- url: "/",
-
- // Example of an inline template string. By default, templates
- // will populate the ui-view within the parent state's template.
- // For top level states, like this one, the parent template is
- // the index.html file. So this template will be inserted into the
- // ui-view within index.html.
- template: '
Welcome to the UI-Router Demo
' +
- '
Use the menu above to navigate. ' +
- 'Pay attention to the $state and $stateParams values below.
' +
- '
Click these links—Alice or ' +
- 'Bob—to see a url redirect in action.
'
-
- })
-
- //////////////
- // Contacts //
- //////////////
-
- .state('contacts', {
-
- // With abstract set to true, that means this state can not be explicitly activated.
- // It can only be implicitly activated by activating one of it's children.
- abstract: true,
-
- // This abstract state will prepend '/contacts' onto the urls of all its children.
- url: '/contacts',
-
- // Example of loading a template from a file. This is also a top level state,
- // so this template file will be loaded and then inserted into the ui-view
- // within index.html.
- templateUrl: 'contacts.html',
-
- // Use `resolve` to resolve any asynchronous controller dependencies
- // *before* the controller is instantiated. In this case, since contacts
- // returns a promise, the controller will wait until contacts.all() is
- // resolved before instantiation. Non-promise return values are considered
- // to be resolved immediately.
- resolve: {
- contacts: ['contacts',
- function( contacts){
- return contacts.all();
- }]
- },
-
- // You can pair a controller to your template. There *must* be a template to pair with.
- controller: ['$scope', '$state', 'contacts', 'utils',
- function ( $scope, $state, contacts, utils) {
-
- // Add a 'contacts' field in this abstract parent's scope, so that all
- // child state views can access it in their scopes. Please note: scope
- // inheritance is not due to nesting of states, but rather choosing to
- // nest the templates of those states. It's normal scope inheritance.
- $scope.contacts = contacts;
-
- $scope.goToRandom = function () {
- var randId = utils.newRandomKey($scope.contacts, "id", $state.params.contactId);
-
- // $state.go() can be used as a high level convenience method
- // for activating a state programmatically.
- $state.go('contacts.detail', { contactId: randId });
- };
- }]
- })
-
- /////////////////////
- // Contacts > List //
- /////////////////////
-
- // Using a '.' within a state name declares a child within a parent.
- // So you have a new state 'list' within the parent 'contacts' state.
- .state('contacts.list', {
-
- // Using an empty url means that this child state will become active
- // when its parent's url is navigated to. Urls of child states are
- // automatically appended to the urls of their parent. So this state's
- // url is '/contacts' (because '/contacts' + '').
- url: '',
-
- // IMPORTANT: Now we have a state that is not a top level state. Its
- // template will be inserted into the ui-view within this state's
- // parent's template; so the ui-view within contacts.html. This is the
- // most important thing to remember about templates.
- templateUrl: 'contacts.list.html'
- })
-
- ///////////////////////
- // Contacts > Detail //
- ///////////////////////
-
- // You can have unlimited children within a state. Here is a second child
- // state within the 'contacts' parent state.
- .state('contacts.detail', {
-
- // Urls can have parameters. They can be specified like :param or {param}.
- // If {} is used, then you can also specify a regex pattern that the param
- // must match. The regex is written after a colon (:). Note: Don't use capture
- // groups in your regex patterns, because the whole regex is wrapped again
- // behind the scenes. Our pattern below will only match numbers with a length
- // between 1 and 4.
-
- // Since this state is also a child of 'contacts' its url is appended as well.
- // So its url will end up being '/contacts/{contactId:[0-9]{1,8}}'. When the
- // url becomes something like '/contacts/42' then this state becomes active
- // and the $stateParams object becomes { contactId: 42 }.
- url: '/{contactId:[0-9]{1,4}}',
-
- // If there is more than a single ui-view in the parent template, or you would
- // like to target a ui-view from even higher up the state tree, you can use the
- // views object to configure multiple views. Each view can get its own template,
- // controller, and resolve data.
-
- // View names can be relative or absolute. Relative view names do not use an '@'
- // symbol. They always refer to views within this state's parent template.
- // Absolute view names use a '@' symbol to distinguish the view and the state.
- // So 'foo@bar' means the ui-view named 'foo' within the 'bar' state's template.
- views: {
-
- // So this one is targeting the unnamed view within the parent state's template.
- '': {
- templateUrl: 'contacts.detail.html',
- controller: ['$scope', '$stateParams', 'utils',
- function ( $scope, $stateParams, utils) {
- $scope.contact = utils.findById($scope.contacts, $stateParams.contactId);
- }]
- },
-
- // This one is targeting the ui-view="hint" within the unnamed root, aka index.html.
- // This shows off how you could populate *any* view within *any* ancestor state.
- 'hint@': {
- template: 'This is contacts.detail populating the "hint" ui-view'
- },
-
- // This one is targeting the ui-view="menu" within the parent state's template.
- 'menuTip': {
- // templateProvider is the final method for supplying a template.
- // There is: template, templateUrl, and templateProvider.
- templateProvider: ['$stateParams',
- function ( $stateParams) {
- // This is just to demonstrate that $stateParams injection works for templateProvider.
- // $stateParams are the parameters for the new state we're transitioning to, even
- // though the global '$stateParams' has not been updated yet.
- return 'Contact ID: ' + $stateParams.contactId + '';
- }]
- }
- }
- })
-
- //////////////////////////////
- // Contacts > Detail > Item //
- //////////////////////////////
-
- .state('contacts.detail.item', {
-
- // So following what we've learned, this state's full url will end up being
- // '/contacts/{contactId}/item/:itemId'. We are using both types of parameters
- // in the same url, but they behave identically.
- url: '/item/:itemId',
- views: {
-
- // This is targeting the unnamed ui-view within the parent state 'contact.detail'
- // We wouldn't have to do it this way if we didn't also want to set the 'hint' view below.
- // We could instead just set templateUrl and controller outside of the view obj.
- '': {
- templateUrl: 'contacts.detail.item.html',
- controller: ['$scope', '$stateParams', '$state', 'utils',
- function ( $scope, $stateParams, $state, utils) {
- $scope.item = utils.findById($scope.contact.items, $stateParams.itemId);
-
- $scope.edit = function () {
- // Here we show off go's ability to navigate to a relative state. Using '^' to go upwards
- // and '.' to go down, you can navigate to any relative state (ancestor or descendant).
- // Here we are going down to the child state 'edit' (full name of 'contacts.detail.item.edit')
- $state.go('.edit', $stateParams);
- };
- }]
- },
-
- // Here we see we are overriding the template that was set by 'contact.detail'
- 'hint@': {
- template: ' This is contacts.detail.item overriding the "hint" ui-view'
- }
- }
- })
-
- /////////////////////////////////////
- // Contacts > Detail > Item > Edit //
- /////////////////////////////////////
-
- // Notice that this state has no 'url'. States do not require a url. You can use them
- // simply to organize your application into "places" where each "place" can configure
- // only what it needs. The only way to get to this state is via $state.go (or transitionTo)
- .state('contacts.detail.item.edit', {
- views: {
-
- // This is targeting the unnamed view within the 'contact.detail' state
- // essentially swapping out the template that 'contact.detail.item' had
- // had inserted with this state's template.
- '@contacts.detail': {
- templateUrl: 'contacts.detail.item.edit.html',
- controller: ['$scope', '$stateParams', '$state', 'utils',
- function ( $scope, $stateParams, $state, utils) {
- $scope.item = utils.findById($scope.contact.items, $stateParams.itemId);
- $scope.done = function () {
- // Go back up. '^' means up one. '^.^' would be up twice, to the grandparent.
- $state.go('^', $stateParams);
- };
- }]
- }
- }
- })
-
- ///////////
- // About //
- ///////////
-
- .state('about', {
- url: '/about',
-
- // Showing off how you could return a promise from templateProvider
- templateProvider: ['$timeout',
- function ( $timeout) {
- return $timeout(function () {
- return '