Skip to content

Commit e2b54f2

Browse files
committed
feat(uiSref): add ui-sref-on to expose transition promise
Fixes angular-ui#1863 @see angular-ui#1863 added $q.when
1 parent 2fff59c commit e2b54f2

File tree

2 files changed

+99
-1
lines changed

2 files changed

+99
-1
lines changed

src/stateDirectives.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,12 @@ function $StateRefDirective($state, $timeout) {
134134
if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
135135
// HACK: This is to allow ng-clicks to be processed before the transition is initiated:
136136
var transition = $timeout(function() {
137-
$state.go(ref.state, params, options);
137+
var $transition = $state.go(ref.state, params, options);
138+
if($transition && attrs.uiSrefOn) {
139+
scope.$eval(attrs.uiSrefOn, {
140+
$transition: $q.when($transition)
141+
});
142+
}
138143
});
139144
e.preventDefault();
140145

test/stateDirectivesSpec.js

+93
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,96 @@ describe('uiView controllers or onEnter handlers', function() {
559559
expect(count).toBe(1);
560560
}));
561561
});
562+
563+
564+
ddescribe('uiSrefResolve', function() {
565+
var template = '<div><a ui-sref=".a" ui-sref-on="check($transition)" class="a">A</a></div>';
566+
567+
beforeEach(module('ui.router'));
568+
569+
var $timeout, defer;
570+
571+
beforeEach(module(function($stateProvider) {
572+
$stateProvider.state('top', {
573+
url: ''
574+
}).state('a', {
575+
url: '/a',
576+
template: 'Success',
577+
controller: function(a) {}, // require a
578+
resolve: {
579+
a: function($q) {
580+
defer = $q.defer();
581+
return defer.promise;
582+
}
583+
}
584+
});
585+
}));
586+
587+
beforeEach(inject(function(_$timeout_) {
588+
$timeout = _$timeout_;
589+
}));
590+
591+
function triggerClick(el, options) {
592+
options = angular.extend({
593+
metaKey: false,
594+
ctrlKey: false,
595+
shiftKey: false,
596+
altKey: false,
597+
button: 0
598+
}, options || {});
599+
600+
var e = document.createEvent("MouseEvents");
601+
e.initMouseEvent(
602+
"click", // typeArg of type DOMString, Specifies the event type.
603+
true, // canBubbleArg of type boolean, Specifies whether or not the event can bubble.
604+
true, // cancelableArg of type boolean, Specifies whether or not the event's default action can be prevented.
605+
undefined, // viewArg of type views::AbstractView, Specifies the Event's AbstractView.
606+
0, // detailArg of type long, Specifies the Event's mouse click count.
607+
0, // screenXArg of type long, Specifies the Event's screen x coordinate
608+
0, // screenYArg of type long, Specifies the Event's screen y coordinate
609+
0, // clientXArg of type long, Specifies the Event's client x coordinate
610+
0, // clientYArg of type long, Specifies the Event's client y coordinate
611+
options.ctrlKey, // ctrlKeyArg of type boolean, Specifies whether or not control key was depressed during the Event.
612+
options.altKey, // altKeyArg of type boolean, Specifies whether or not alt key was depressed during the Event.
613+
options.shiftKey, // shiftKeyArg of type boolean, Specifies whether or not shift key was depressed during the Event.
614+
options.metaKey, // metaKeyArg of type boolean, Specifies whether or not meta key was depressed during the Event.
615+
options.button, // buttonArg of type unsigned short, Specifies the Event's mouse button.
616+
null // relatedTargetArg of type EventTarget
617+
);
618+
el[0].dispatchEvent(e);
619+
}
620+
621+
it('should execute ui-sref-on code on click', inject(function($rootScope, $q, $compile, $state) {
622+
el = angular.element(template);
623+
template = $compile(el)($rootScope);
624+
$rootScope.$digest();
625+
626+
var a = angular.element(template[0].querySelector('.a'));
627+
628+
var state = 'start', transition = null;
629+
$rootScope.check = function(_transition) {
630+
state = 'resolving';
631+
transition = _transition;
632+
633+
transition.then(function() {
634+
state = 'resolved';
635+
});
636+
};
637+
638+
expect(state).toBe('start');
639+
expect(transition).toBeNull();
640+
expect(a.attr('class')).toBe('a');
641+
642+
triggerClick(a);
643+
$timeout.flush();
644+
645+
expect(state).toBe('resolving');
646+
expect(transition).not.toBeNull();
647+
648+
defer.resolve('done');
649+
$timeout.flush();
650+
651+
expect(state).toBe('resolved');
652+
}));
653+
654+
});

0 commit comments

Comments
 (0)