Skip to content

Commit 9668a0d

Browse files
committed
ui-sref should enable relative states & param inheritance
1 parent c32b981 commit 9668a0d

File tree

3 files changed

+61
-38
lines changed

3 files changed

+61
-38
lines changed

src/state.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
321321
};
322322

323323
$state.href = function href(stateOrName, params, options) {
324-
options = extend({ lossy: true }, options || {});
325-
var state = findState(stateOrName);
324+
options = extend({ lossy: true, inherit: false, relative: $state.$current }, options || {});
325+
var state = findState(stateOrName, options.relative);
326+
327+
params = inheritParams($stateParams, params || {}, $state.$current, state);
326328
var nav = (state && options.lossy) ? state.navigable : state;
327329
var url = (nav && nav.url) ? nav.url.format(normalize(state.params, params || {})) : null;
328330
return !$locationProvider.html5Mode() && url ? "#" + url : url;

src/stateDirectives.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function $StateRefDirective($state) {
3939

4040
element.bind("click", function(e) {
4141
if ((e.which == 1) && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
42-
$state.transitionTo(ref.state, params);
42+
$state.go(ref.state, params);
4343
scope.$apply();
4444
e.preventDefault();
4545
}

test/stateDirectivesSpec.js

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
describe('uiStateRef', function() {
22

3+
var el, scope, document;
4+
35
beforeEach(module('ui.state'));
46

57
beforeEach(module(function($stateProvider) {
@@ -12,42 +14,41 @@ describe('uiStateRef', function() {
1214
}).state('contacts.item.detail', {});
1315
}));
1416

15-
describe('links', function() {
16-
var el, scope, document;
17+
beforeEach(inject(function($document) {
18+
document = $document[0];
19+
}));
1720

18-
beforeEach(inject(function($document) {
19-
document = $document[0];
20-
}));
21+
function triggerClick(el, options) {
22+
options = angular.extend({
23+
metaKey: false,
24+
ctrlKey: false,
25+
shiftKey: false,
26+
altKey: false,
27+
button: 0
28+
}, options || {});
29+
30+
var e = document.createEvent("MouseEvents");
31+
e.initMouseEvent(
32+
"click", // typeArg of type DOMString, Specifies the event type.
33+
true, // canBubbleArg of type boolean, Specifies whether or not the event can bubble.
34+
true, // cancelableArg of type boolean, Specifies whether or not the event's default action can be prevented.
35+
undefined, // viewArg of type views::AbstractView, Specifies the Event's AbstractView.
36+
0, // detailArg of type long, Specifies the Event's mouse click count.
37+
0, // screenXArg of type long, Specifies the Event's screen x coordinate
38+
0, // screenYArg of type long, Specifies the Event's screen y coordinate
39+
0, // clientXArg of type long, Specifies the Event's client x coordinate
40+
0, // clientYArg of type long, Specifies the Event's client y coordinate
41+
options.ctrlKey, // ctrlKeyArg of type boolean, Specifies whether or not control key was depressed during the Event.
42+
options.altKey, // altKeyArg of type boolean, Specifies whether or not alt key was depressed during the Event.
43+
options.shiftKey, // shiftKeyArg of type boolean, Specifies whether or not shift key was depressed during the Event.
44+
options.metaKey, // metaKeyArg of type boolean, Specifies whether or not meta key was depressed during the Event.
45+
options.button, // buttonArg of type unsigned short, Specifies the Event's mouse button.
46+
null // relatedTargetArg of type EventTarget
47+
);
48+
el[0].dispatchEvent(e);
49+
}
2150

22-
function triggerClick(el, options) {
23-
options = angular.extend({
24-
metaKey: false,
25-
ctrlKey: false,
26-
shiftKey: false,
27-
altKey: false,
28-
button: 0
29-
}, options || {});
30-
31-
var e = document.createEvent("MouseEvents");
32-
e.initMouseEvent(
33-
"click", // typeArg of type DOMString, Specifies the event type.
34-
true, // canBubbleArg of type boolean, Specifies whether or not the event can bubble.
35-
true, // cancelableArg of type boolean, Specifies whether or not the event's default action can be prevented.
36-
undefined, // viewArg of type views::AbstractView, Specifies the Event's AbstractView.
37-
0, // detailArg of type long, Specifies the Event's mouse click count.
38-
0, // screenXArg of type long, Specifies the Event's screen x coordinate
39-
0, // screenYArg of type long, Specifies the Event's screen y coordinate
40-
0, // clientXArg of type long, Specifies the Event's client x coordinate
41-
0, // clientYArg of type long, Specifies the Event's client y coordinate
42-
options.ctrlKey, // ctrlKeyArg of type boolean, Specifies whether or not control key was depressed during the Event.
43-
options.altKey, // altKeyArg of type boolean, Specifies whether or not alt key was depressed during the Event.
44-
options.shiftKey, // shiftKeyArg of type boolean, Specifies whether or not shift key was depressed during the Event.
45-
options.metaKey, // metaKeyArg of type boolean, Specifies whether or not meta key was depressed during the Event.
46-
options.button, // buttonArg of type unsigned short, Specifies the Event's mouse button.
47-
null // relatedTargetArg of type EventTarget
48-
);
49-
el[0].dispatchEvent(e);
50-
}
51+
describe('links', function() {
5152

5253
beforeEach(inject(function($rootScope, $compile) {
5354
el = angular.element('<a ui-sref="contacts.item.detail({ id: contact.id })">Details</a>');
@@ -59,7 +60,6 @@ describe('uiStateRef', function() {
5960
scope.$digest();
6061
}));
6162

62-
6363
it('should generate the correct href', function() {
6464
expect(el.attr('href')).toBe('#/contacts/5');
6565
});
@@ -138,4 +138,25 @@ describe('uiStateRef', function() {
138138
expect(el.attr('action')).toBe('#/contacts/5');
139139
});
140140
});
141+
142+
describe('relative transitions', function() {
143+
144+
beforeEach(inject(function($rootScope, $compile, $state) {
145+
$state.transitionTo("contacts.item", { id: 5 });
146+
el = angular.element('<a ui-sref=".detail">Details</a>');
147+
scope = $rootScope;
148+
scope.$apply();
149+
150+
$compile(el)(scope);
151+
scope.$digest();
152+
}));
153+
154+
it('should work', inject(function ($state, $stateParams, $q) {
155+
triggerClick(el);
156+
$q.flush();
157+
158+
expect($state.$current.name).toBe("contacts.item.detail");
159+
expect($state.params).toEqual({ id: '5' });
160+
}));
161+
});
141162
});

0 commit comments

Comments
 (0)