Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added 'state' to state reload method #1795

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -820,11 +820,33 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* });
* </pre>
*
* @param {string} state A state name which is the root of the resolves to re-resolved.
* @example
* <pre>
* //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'
* //and current state is 'contacts.detail.item'
* var app angular.module('app', ['ui.router']);
*
* app.controller('ctrl', function ($scope, $state) {
* $scope.reload = function(){
* //will reload 'contact.detail' and 'contact.detail.item' states
* $state.reload('contact.detail');
* }
* });
* </pre>
*
* `reload()` is just an alias for:
* <pre>
* $state.transitionTo($state.current, $stateParams, {
* reload: true, inherit: false, notify: true
* });
* </pre>

* @returns {promise} A promise representing the state of the new transition. See
* {@link ui.router.state.$state#methods_go $state.go}.
*/
$state.reload = function reload() {
return $state.transitionTo($state.current, $stateParams, { reload: true, inherit: false, notify: true });
$state.reload = function reload(state) {
return $state.transitionTo($state.current, $stateParams, { reload: true, inherit: false, notify: true, reloadState: state });
};

/**
Expand Down Expand Up @@ -931,14 +953,16 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params
* have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
* use this when you want to force a reload when *everything* is the same, including search params.
* - **'reloadState'** - {string=null}, A state name which will be the root state to reload from.
* should be used with options.reload=true
*
* @returns {promise} A promise representing the state of the new transition. See
* {@link ui.router.state.$state#methods_go $state.go}.
*/
$state.transitionTo = function transitionTo(to, toParams, options) {
toParams = toParams || {};
options = extend({
location: true, inherit: false, relative: null, notify: true, reload: false, $retry: false
location: true, inherit: false, relative: null, notify: true, reload: false, $retry: false, reloadState : null
}, options || {});

var from = $state.$current, fromParams = $state.params, fromPath = from.path;
Expand Down Expand Up @@ -982,14 +1006,24 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
keep++;
state = toPath[keep];
}
} else if (options.reloadState) {
if (!isDefined(findState(options.reloadState))) {
throw new Error("No such state '" + options.reloadState + "'");
}

while (state && state === fromPath[keep] && state.toString().toLowerCase() !== options.reloadState.toLowerCase()) {
locals = toLocals[keep] = state.locals;
keep++;
state = toPath[keep];
}
}

// If we're going to the same state and all locals are kept, we've got nothing to do.
// But clear 'transition', as we still want to cancel any other pending transitions.
// TODO: We may not want to bump 'transition' if we're called from a location change
// that we've initiated ourselves, because we might accidentally abort a legitimate
// transition initiated from code?
if (shouldTriggerReload(to, from, locals, options)) {
if (!options.reloadState && shouldTriggerReload(to, from, locals, options)) {
if (to.self.reloadOnSearch !== false) $urlRouter.update();
$state.transition = null;
return $q.when($state.current);
Expand Down
62 changes: 61 additions & 1 deletion test/stateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,30 @@ describe('state', function () {
// State param inheritance tests. param1 is inherited by sub1 & sub2;
// param2 should not be transferred (unless explicitly set).
.state('root', { url: '^/root?param1' })
.state('root.sub1', {url: '/1?param2' });
.state('root.sub1', {url: '/1?param2' })
.state('logA', {
url: "/logA",
template: "<div> <div ui-view/></div>",
controller: function() {log += "logA;"}
})
.state('logA.logB', {
url: "/logB",
views:{
'':{
template: "<div> <div ui-view/></div>",
controller: function() {log += "logB;"}
}
}
})
.state('logA.logB.logC', {
url: "/logC",
views:{
'':{
template: "<div> <div ui-view/></div>",
controller: function() {log += "logC;"}
}
}
})
$stateProvider.state('root.sub2', {url: '/2?param2' });

$provide.value('AppInjectable', AppInjectable);
Expand Down Expand Up @@ -531,6 +554,40 @@ describe('state', function () {
$q.flush();
expect(log).toBe('Success!controller;Success!controller;');
}));

it('should invoke the controllers by state', inject(function ($state, $q, $timeout, $rootScope, $compile) {
$compile('<div> <div ui-view/></div>')($rootScope);
$state.transitionTo('logA.logB.logC');
$q.flush();
expect(log).toBe('logA;logB;logC;');

log = '';
$state.reload('logA');
$q.flush();
expect(log).toBe('logA;logB;logC;');

log = '';
$state.reload('logA.logB');
$q.flush();
expect(log).toBe('logB;logC;');

log = '';
$state.reload('logA.logB.logC');
$q.flush();
expect(log).toBe('logC;');

}));

it('should throw an exception for invalid reload state', inject(function ($state, $q, $timeout, $rootScope, $compile) {
$compile('<div> <div ui-view/></div>')($rootScope);
$state.transitionTo('logA.logB.logC');
$q.flush();
expect(log).toBe('logA;logB;logC;');

expect(function(){
$state.reload('logInvalid')}
).toThrow("No such state 'logInvalid'");
}));
});

describe('.is()', function () {
Expand Down Expand Up @@ -784,6 +841,9 @@ describe('state', function () {
'home.item',
'home.redirect',
'json',
'logA',
'logA.logB',
'logA.logB.logC',
'resolveFail',
'resolveTimeout',
'root',
Expand Down