Skip to content

Commit 4bd31b1

Browse files
committed
feat(uiSref): add ui-sref-on attribute
Fixes angular-ui#1863, supersedes angular-ui#1877
1 parent dba25db commit 4bd31b1

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/stateDirectives.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ function stateContext(el) {
4141
* using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`,
4242
* and `reload`.
4343
*
44+
* You can invoke an expression when this state transition is initiated using
45+
* the `ui-sref-on` attribute. The promise returned by {@link
46+
* ui.router.state.$state#methods_go $state.go()} is injected into the expression as
47+
* `$template`.
48+
*
4449
* @example
4550
* Here's an example of how you'd use ui-sref and how it would compile. If you have the
4651
* following template:
@@ -75,6 +80,7 @@ function stateContext(el) {
7580
*
7681
* @param {string} ui-sref 'stateName' can be any valid absolute or relative state
7782
* @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()}
83+
* @param {expression} ui-sref-on expression to evaluate when transition starts. Result of {@link ui.router.state.$state#methods_go $state.go()} is injected as '$transition'
7884
*/
7985
$StateRefDirective.$inject = ['$state', '$timeout'];
8086
function $StateRefDirective($state, $timeout) {
@@ -134,7 +140,12 @@ function $StateRefDirective($state, $timeout) {
134140
if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
135141
// HACK: This is to allow ng-clicks to be processed before the transition is initiated:
136142
var transition = $timeout(function() {
137-
$state.go(ref.state, params, options);
143+
var $transition = $state.go(ref.state, params, options);
144+
if ($transition && attrs.uiSrefOn) {
145+
scope.$eval(attrs.uiSrefOn, {
146+
$transition: $transition
147+
});
148+
}
138149
});
139150
e.preventDefault();
140151

test/stateDirectivesSpec.js

+28
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,34 @@ describe('uiStateRef', function() {
389389
expect(transitionOptions.notify).toBeUndefined();
390390
}));
391391
});
392+
393+
describe('transition expression', function() {
394+
beforeEach(inject(function($rootScope, $compile) {
395+
el = angular.element('<a ui-sref="contacts.item.detail({id: 5})" ui-sref-on="loading = $transition">Details</a>');
396+
scope = $rootScope;
397+
scope.loading = null;
398+
399+
$compile(el)(scope);
400+
scope.$digest();
401+
}));
402+
403+
it('applies an expression when a transition begins', inject(function($rootScope, $timeout, $state) {
404+
var newState;
405+
406+
expect($rootScope.loading).toBe(null);
407+
triggerClick(el);
408+
$timeout.flush();
409+
410+
expect($rootScope.loading.then).toEqual(jasmine.any(Function));
411+
412+
$rootScope.loading.then(function(_newState) {
413+
newState = _newState;
414+
});
415+
416+
$rootScope.$digest();
417+
expect(newState).toEqual($state.get('contacts.item.detail'));
418+
}));
419+
});
392420
});
393421

394422
describe('uiSrefActive', function() {

0 commit comments

Comments
 (0)