Skip to content

Commit 91a5684

Browse files
committed
Merge pull request #813 from roryf/ui-sref-options
feat(uiSref): add support for transition options
2 parents 66070cc + 2ed7a72 commit 91a5684

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/stateDirectives.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ function stateContext(el) {
3535
* to the state that the link lives in, in other words the state that loaded the
3636
* template containing the link.
3737
*
38+
* You can specify options to pass to {@link ui.router.state.$state#go $state.go()}
39+
* using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`,
40+
* and `reload`.
41+
*
3842
* @example
3943
* Here's an example of how you'd use ui-sref and how it would compile. If you have the
4044
* following template:
@@ -63,12 +67,17 @@ function stateContext(el) {
6367
* <a href="#/contacts/3" ui-sref="contacts.detail({ id: contact.id })">Bob</a>
6468
* </li>
6569
* </ul>
70+
*
71+
* <a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
6672
* </pre>
6773
*
6874
* @param {string} ui-sref 'stateName' can be any valid absolute or relative state
75+
* @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()}
6976
*/
7077
$StateRefDirective.$inject = ['$state', '$timeout'];
7178
function $StateRefDirective($state, $timeout) {
79+
var allowedOptions = ['location', 'inherit', 'reload'];
80+
7281
return {
7382
restrict: 'A',
7483
require: '?^uiSrefActive',
@@ -78,11 +87,21 @@ function $StateRefDirective($state, $timeout) {
7887
var isForm = element[0].nodeName === "FORM";
7988
var attr = isForm ? "action" : "href", nav = true;
8089

90+
var options = {
91+
relative: base
92+
};
93+
var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};
94+
angular.forEach(allowedOptions, function(option) {
95+
if (option in optionsOverride) {
96+
options[option] = optionsOverride[option];
97+
}
98+
});
99+
81100
var update = function(newVal) {
82101
if (newVal) params = newVal;
83102
if (!nav) return;
84103

85-
var newHref = $state.href(ref.state, params, { relative: base });
104+
var newHref = $state.href(ref.state, params, options);
86105

87106
if (uiSrefActive) {
88107
uiSrefActive.$$setStateInfo(ref.state, params);
@@ -109,7 +128,7 @@ function $StateRefDirective($state, $timeout) {
109128
if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {
110129
// HACK: This is to allow ng-clicks to be processed before the transition is initiated:
111130
$timeout(function() {
112-
$state.go(ref.state, params, { relative: base });
131+
$state.go(ref.state, params, options);
113132
});
114133
e.preventDefault();
115134
}

test/stateDirectivesSpec.js

+26
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,32 @@ describe('uiStateRef', function() {
257257
expect($state.$current.name).toBe("contacts");
258258
}));
259259
});
260+
261+
describe('transition options', function() {
262+
263+
beforeEach(inject(function($rootScope, $compile, $state) {
264+
el = angular.element('<a ui-sref="contacts.item.detail({ id: contact.id })" ui-sref-opts="{ reload: true, notify: true }">Details</a>');
265+
scope = $rootScope;
266+
scope.contact = { id: 5 };
267+
268+
$compile(el)(scope);
269+
scope.$digest();
270+
}));
271+
272+
it('uses allowed transition options', inject(function($q, $timeout, $state) {
273+
var transitionOptions;
274+
275+
spyOn($state, 'go').andCallFake(function(state, params, options) {
276+
transitionOptions = options;
277+
});
278+
279+
triggerClick(el);
280+
$timeout.flush();
281+
282+
expect(transitionOptions.reload).toEqual(true);
283+
expect(transitionOptions.notify).toBeUndefined();
284+
}));
285+
});
260286
});
261287

262288
describe('uiSrefActive', function() {

0 commit comments

Comments
 (0)