diff --git a/src/stateDirectives.js b/src/stateDirectives.js
index b39f7b6c8..83234a60e 100644
--- a/src/stateDirectives.js
+++ b/src/stateDirectives.js
@@ -33,7 +33,7 @@ function clickHook(el, $state, $timeout, type, current) {
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.state, target.params, target.options);
+ $state.go(target.state === '.' ? $state.current.name : target.state, target.params, target.options);
});
e.preventDefault();
@@ -128,7 +128,7 @@ function $StateRefDirective($state, $timeout) {
var update = function(val) {
if (val) def.params = angular.copy(val);
- def.href = $state.href(ref.state, def.params, def.options);
+ def.href = $state.href(ref.state === '.' ? $state.current.name : ref.state, def.params, def.options);
if (active) active.$$addStateInfo(ref.state, def.params);
if (def.href !== null) attrs.$set(type.attr, def.href);
@@ -139,6 +139,13 @@ function $StateRefDirective($state, $timeout) {
def.params = angular.copy(scope.$eval(ref.paramExpr));
}
update();
+ if (ref.state === '.') {
+ scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
+ if (fromState.name !== toState.name) {
+ update();
+ }
+ });
+ }
if (!type.clickable) return;
element.bind("click", clickHook(element, $state, $timeout, type, function() { return def; }));
diff --git a/test/stateDirectivesSpec.js b/test/stateDirectivesSpec.js
index a9c0f120f..cc8478e94 100644
--- a/test/stateDirectivesSpec.js
+++ b/test/stateDirectivesSpec.js
@@ -1,15 +1,15 @@
describe('uiStateRef', function() {
- var timeoutFlush, el, el2, template, scope, document, _locationProvider;
+ var timeoutFlush, el, el2, el3, template, scope, document, _locationProvider;
beforeEach(module('ui.router'));
beforeEach(module(function($stateProvider, $locationProvider) {
_locationProvider = $locationProvider;
$stateProvider.state('top', {
- url: ''
+ url: '?param'
}).state('contacts', {
- url: '/contacts',
+ url: '/contacts?param',
template: 'Person '
}).state('contacts.item', {
url: '/{id:int}',
@@ -79,12 +79,14 @@ describe('uiStateRef', function() {
function buildDOM($rootScope, $compile, $timeout) {
el = angular.element('Details');
el2 = angular.element('Top');
+ el3 = angular.element('Param 1');
scope = $rootScope;
scope.contact = { id: 5 };
scope.$apply();
$compile(el)(scope);
$compile(el2)(scope);
+ $compile(el3)(scope);
scope.$digest();
timeoutFlush = function () {
@@ -103,6 +105,7 @@ describe('uiStateRef', function() {
it('should generate the correct href', function() {
expect(el.attr('href')).toBe('#/contacts/5');
expect(el2.attr('href')).toBe('#');
+ expect(el3.attr('href')).toBe('#?param=1');
});
it('should update the href when parameters change', function() {
@@ -289,6 +292,16 @@ describe('uiStateRef', function() {
expect($state.current.name).toEqual('top');
expect($stateParams).toEqualData({});
}));
+
+ it('should not transition state and change state params on "." pesudostate click', inject(function($state, $stateParams, $q){
+ triggerClick(el);
+ timeoutFlush();
+ triggerClick(el3);
+ timeoutFlush();
+ $q.flush();
+ expect($state.current.name).toEqual('contacts.item.detail');
+ expect($stateParams).toEqualData({param: '1', id: 5});
+ }));
});
describe('links with dynamic state definitions', function () {