Skip to content

Commit 3c1bd0e

Browse files
fix(ui-sref): Update params-only sref when state changes
- ui-sref="{ id: 123 }" should always link to the current state with the param values Closes #1031 Supersedes and Closes #2541
1 parent 98a5386 commit 3c1bd0e

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

src/ng1/directives/stateDirectives.ts

+22-16
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ import { IAugmentedJQuery, ITimeoutService, IScope, IInterpolateService } from "
1010

1111
import {
1212
Obj, extend, forEach, tail, isString, isObject, parse, noop, unnestR, identity, uniqR, inArray, removeFrom,
13-
RawParams, PathNode, StateOrName, StateService, TransitionService, StateDeclaration, UIRouter
13+
RawParams, PathNode, StateOrName, StateService, StateDeclaration, UIRouter
1414
} from "ui-router-core";
1515
import { UIViewData } from "./viewDirective";
1616

1717
/** @hidden */
18-
function parseStateRef(ref: string, current: string) {
19-
let preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
20-
if (preparsed) ref = current + '(' + preparsed[1] + ')';
21-
parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
18+
function parseStateRef(ref: string) {
19+
let paramsOnly = ref.match(/^\s*({[^}]*})\s*$/), parsed;
20+
if (paramsOnly) ref = '(' + paramsOnly[1] + ')';
21+
22+
parsed = ref.replace(/\n/g, " ").match(/^\s*([^(]*?)\s*(\((.*)\))?\s*$/);
2223
if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'");
23-
return { state: parsed[1], paramExpr: parsed[3] || null };
24+
return { state: parsed[1] || null, paramExpr: parsed[3] || null };
2425
}
2526

2627
/** @hidden */
@@ -57,7 +58,8 @@ function clickHook(el: IAugmentedJQuery, $state: StateService, $timeout: ITimeou
5758
if (!(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || el.attr('target'))) {
5859
// HACK: This is to allow ng-clicks to be processed before the transition is initiated:
5960
var transition = $timeout(function () {
60-
$state.go(target.uiState, target.uiStateParams, target.uiStateOpts);
61+
let state = target.uiState || $state.current;
62+
$state.go(state, target.uiStateParams, target.uiStateOpts);
6163
});
6264
e.preventDefault();
6365

@@ -150,21 +152,22 @@ let uiSref = ['$uiRouter', '$timeout',
150152
restrict: 'A',
151153
require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
152154
link: function (scope: IScope, element: IAugmentedJQuery, attrs: any, uiSrefActive: any) {
153-
var ref = parseStateRef(attrs.uiSref, $state.current.name);
154-
var def = { uiState: ref.state } as Def;
155+
var ref = parseStateRef(attrs.uiSref);
155156
var type = getTypeInfo(element);
156157
var active = uiSrefActive[1] || uiSrefActive[0];
157158
var unlinkInfoFn: Function = null;
158159
var hookFn;
159160

161+
var def = { uiState: ref.state } as Def;
160162
def.uiStateOpts = extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});
161163

162164
var update = function (val?: any) {
163165
if (val) def.uiStateParams = angular.copy(val);
164-
def.href = $state.href(ref.state, def.uiStateParams, def.uiStateOpts);
166+
let state = def.uiState || $uiRouter.globals.current;
167+
def.href = $state.href(state, def.uiStateParams, def.uiStateOpts);
165168

166169
if (unlinkInfoFn) unlinkInfoFn();
167-
if (active) unlinkInfoFn = active.$$addStateInfo(ref.state, def.uiStateParams);
170+
if (active) unlinkInfoFn = active.$$addStateInfo(state, def.uiStateParams);
168171
if (def.href !== null) attrs.$set(type.attr, def.href);
169172
};
170173

@@ -177,6 +180,7 @@ let uiSref = ['$uiRouter', '$timeout',
177180
update();
178181

179182
scope.$on('$destroy', <any> $uiRouter.stateRegistry.onStatesChanged(() => update()));
183+
scope.$on('$destroy', <any> $uiRouter.transitionService.onSuccess({}, () => update()));
180184

181185
if (!type.clickable) return;
182186
hookFn = clickHook(element, $state, $timeout, type, function () {
@@ -239,10 +243,11 @@ let uiState = ['$uiRouter', '$timeout',
239243
var hookFn;
240244

241245
function update() {
242-
def.href = $state.href(def.uiState, def.uiStateParams, def.uiStateOpts);
246+
let state = def.uiState || $uiRouter.globals.current;
247+
def.href = $state.href(state, def.uiStateParams, def.uiStateOpts);
243248

244249
if (unlinkInfoFn) unlinkInfoFn();
245-
if (active) unlinkInfoFn = active.$$addStateInfo(def.uiState, def.uiStateParams);
250+
if (active) unlinkInfoFn = active.$$addStateInfo(state, def.uiStateParams);
246251
if (def.href) attrs.$set(type.attr, def.href);
247252
}
248253

@@ -259,6 +264,7 @@ let uiState = ['$uiRouter', '$timeout',
259264
});
260265

261266
scope.$on('$destroy', <any> $uiRouter.stateRegistry.onStatesChanged(() => update()));
267+
scope.$on('$destroy', <any> $uiRouter.transitionService.onSuccess({}, () => update()));
262268
update();
263269

264270
if (!type.clickable) return;
@@ -360,7 +366,7 @@ let uiSrefActive = ['$state', '$stateParams', '$interpolate', '$uiRouter',
360366
restrict: "A",
361367
controller: ['$scope', '$element', '$attrs',
362368
function ($scope: IScope, $element: IAugmentedJQuery, $attrs: any) {
363-
var states: StateData[] = [],
369+
let states: StateData[] = [],
364370
activeEqClass: string,
365371
uiSrefActive: any;
366372

@@ -379,7 +385,7 @@ let uiSrefActive = ['$state', '$stateParams', '$interpolate', '$uiRouter',
379385
if (isObject(uiSrefActive)) {
380386
forEach(uiSrefActive, function (stateOrName: StateOrName, activeClass: string) {
381387
if (isString(stateOrName)) {
382-
var ref = parseStateRef(stateOrName, $state.current.name);
388+
let ref = parseStateRef(stateOrName);
383389
addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
384390
}
385391
});
@@ -392,7 +398,7 @@ let uiSrefActive = ['$state', '$stateParams', '$interpolate', '$uiRouter',
392398
if (isObject(uiSrefActive) && states.length > 0) {
393399
return;
394400
}
395-
var deregister = addState(newState, newParams, uiSrefActive);
401+
let deregister = addState(newState, newParams, uiSrefActive);
396402
update();
397403
return deregister;
398404
};

0 commit comments

Comments
 (0)