Skip to content

Commit

Permalink
fix(ui-sref): Update params-only sref when state changes
Browse files Browse the repository at this point in the history
- ui-sref="{ id: 123 }" should always link to the current state with the param values

Closes #1031
Supersedes and Closes #2541
  • Loading branch information
christopherthielen committed Nov 8, 2016
1 parent 98a5386 commit 3c1bd0e
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions src/ng1/directives/stateDirectives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import { IAugmentedJQuery, ITimeoutService, IScope, IInterpolateService } from "

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

/** @hidden */
function parseStateRef(ref: string, current: string) {
let preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed;
if (preparsed) ref = current + '(' + preparsed[1] + ')';
parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/);
function parseStateRef(ref: string) {
let paramsOnly = ref.match(/^\s*({[^}]*})\s*$/), parsed;
if (paramsOnly) ref = '(' + paramsOnly[1] + ')';

parsed = ref.replace(/\n/g, " ").match(/^\s*([^(]*?)\s*(\((.*)\))?\s*$/);
if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'");
return { state: parsed[1], paramExpr: parsed[3] || null };
return { state: parsed[1] || null, paramExpr: parsed[3] || null };
}

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

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

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

var update = function (val?: any) {
if (val) def.uiStateParams = angular.copy(val);
def.href = $state.href(ref.state, def.uiStateParams, def.uiStateOpts);
let state = def.uiState || $uiRouter.globals.current;
def.href = $state.href(state, def.uiStateParams, def.uiStateOpts);

if (unlinkInfoFn) unlinkInfoFn();
if (active) unlinkInfoFn = active.$$addStateInfo(ref.state, def.uiStateParams);
if (active) unlinkInfoFn = active.$$addStateInfo(state, def.uiStateParams);
if (def.href !== null) attrs.$set(type.attr, def.href);
};

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

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

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

function update() {
def.href = $state.href(def.uiState, def.uiStateParams, def.uiStateOpts);
let state = def.uiState || $uiRouter.globals.current;
def.href = $state.href(state, def.uiStateParams, def.uiStateOpts);

if (unlinkInfoFn) unlinkInfoFn();
if (active) unlinkInfoFn = active.$$addStateInfo(def.uiState, def.uiStateParams);
if (active) unlinkInfoFn = active.$$addStateInfo(state, def.uiStateParams);
if (def.href) attrs.$set(type.attr, def.href);
}

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

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

if (!type.clickable) return;
Expand Down Expand Up @@ -360,7 +366,7 @@ let uiSrefActive = ['$state', '$stateParams', '$interpolate', '$uiRouter',
restrict: "A",
controller: ['$scope', '$element', '$attrs',
function ($scope: IScope, $element: IAugmentedJQuery, $attrs: any) {
var states: StateData[] = [],
let states: StateData[] = [],
activeEqClass: string,
uiSrefActive: any;

Expand All @@ -379,7 +385,7 @@ let uiSrefActive = ['$state', '$stateParams', '$interpolate', '$uiRouter',
if (isObject(uiSrefActive)) {
forEach(uiSrefActive, function (stateOrName: StateOrName, activeClass: string) {
if (isString(stateOrName)) {
var ref = parseStateRef(stateOrName, $state.current.name);
let ref = parseStateRef(stateOrName);
addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
}
});
Expand All @@ -392,7 +398,7 @@ let uiSrefActive = ['$state', '$stateParams', '$interpolate', '$uiRouter',
if (isObject(uiSrefActive) && states.length > 0) {
return;
}
var deregister = addState(newState, newParams, uiSrefActive);
let deregister = addState(newState, newParams, uiSrefActive);
update();
return deregister;
};
Expand Down

0 comments on commit 3c1bd0e

Please sign in to comment.