I have searched for a similar question but the ones that came up seem slightly different. I am trying to change the ui-sref=\'\' of a link dynamically (this link points to t
I managed to implement it this way (I'm using the controllerAs variant though - not via $scope).
Template
<button ui-sref="main({ i18n: '{{ ctrlAs.locale }}' })">Home</button>
Controller
var vm = this;
vm.locale = 'en'; // or whatever dynamic value you prepare
Also see the documentation to ui-sref
where you can pass params:
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
this is just working for me
in controller
$scope.createState = 'stateName';
in view
ui-sref="{{ createState }}"
For manage multiple dynamic params using ui-sref, here my solution :
Html : ('MyPage.html')
<button type="button" ui-sref="myState(configParams())">
Controller : ('MyCtrl')
.controller('MyCtrl', function ($scope) {
$scope.params = {};
$scope.configParams = function() {
$scope.params.param1 = 'something';
$scope.params.param2 = 'oh again?';
$scope.params.param3 = 'yes more and more!';
//etc ...
return $scope.params;
};
}
stateProvider : ('myState')
$stateProvider
.state('myState', {
url: '/name/subname?param1¶m2¶m3',
templateUrl: 'MyPage.html',
controller: 'MyCtrl'
});
Enjoy !
The best approach is to make use of uiRouter's $state.go('stateName', {params})
on button's ng-click
directive. And disable the button if no option is selected.
HTML
<select ng-model="selected" ng-options="option as option.text for option in options"></select>
<button ng-disabled="!selected" type="button" ng-click="ctrl.next()">Next</button>
Controller
function Controller($scope, $state){
this.options = [{
text: 'Option One',
state: 'app.one',
params: {
param1: 'a',
param2: 'b'
}
},{
text: 'Option Two',
state: 'app.two',
params: {
param1: 'c',
param2: 'd'
}
},{
text: 'Option Three',
state: 'app.three',
params: {
param1: 'e',
param2: 'f'
}
}];
this.next = function(){
if(scope.selected){
$state.go($scope.selected.state, $scope.selected.params || {});
}
};
}
State
$stateProvider.state('wizard', {
url: '/wizard/:param1/:param2', // or '/wizard?param1¶m2'
templateUrl: 'wizard.html',
controller: 'Controller as ctrl'
});
After trying various solutions I found the problem in the angular.ui.router
code.
The problem comes from the fact that ui.router update
method is triggered with the ref.state
which means that it is not possible to update the value of the href
used when the element is clicked.
Here are 2 solutions to solve the problem:
module.directive('dynamicSref', function () {
return {
restrict: 'A',
scope: {
state: '@dynamicSref',
params: '=?dynamicSrefParams'
},
link: function ($scope, $element) {
var updateHref = function () {
if ($scope.state) {
var href = $rootScope.$state.href($scope.state, $scope.params);
$element.attr('href', href);
}
};
$scope.$watch('state', function (newValue, oldValue) {
if (newValue !== oldValue) {
updateHref();
}
});
$scope.$watch('params', function (newValue, oldValue) {
if (newValue !== oldValue) {
updateHref();
}
});
updateHref();
}
};
});
The HTML to use it is quite simple :
<a dynamic-sref="home.mystate"
dynamic-sref-params="{ param1 : scopeParam }">
Link
</a>
In angular.router.js your will find the directive $StateRefDirective
(line 4238 for version 0.3).
Change the directive code to :
function $StateRefDirective($state, $timeout) {
return {
restrict: 'A',
require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
link: function (scope, element, attrs, uiSrefActive) {
var ref = parseStateRef(attrs.uiSref, $state.current.name);
var def = { state: ref.state, href: null, params: null };
var type = getTypeInfo(element);
var active = uiSrefActive[1] || uiSrefActive[0];
var unlinkInfoFn = null;
var hookFn;
def.options = extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});
var update = function (val) {
if (val) def.params = angular.copy(val);
def.href = $state.href(ref.state, def.params, def.options);
if (unlinkInfoFn) unlinkInfoFn();
if (active) unlinkInfoFn = active.$$addStateInfo(ref.state, def.params);
if (def.href !== null) attrs.$set(type.attr, def.href);
};
if (ref.paramExpr) {
scope.$watch(ref.paramExpr, function (val) { if (val !== def.params) update(val); }, true);
def.params = angular.copy(scope.$eval(ref.paramExpr));
}
// START CUSTOM CODE : Ability to have a 2 way binding on ui-sref directive
if (typeof attrs.uiSrefDynamic !== "undefined") {
attrs.$observe('uiSref', function (val) {
update(val);
if (val) {
var state = val.split('(')[0];
def.state = state;
$(element).attr('href', $state.href(def.state, def.params, def.options));
}
});
}
// END OF CUSTOM CODE
update();
if (!type.clickable) return;
hookFn = clickHook(element, $state, $timeout, type, function () { return def; });
element.bind("click", hookFn);
scope.$on('$destroy', function () {
element.unbind("click", hookFn);
});
}
};
}
Or just something like this:
<a ui-sref="{{ condition ? 'stateA' : 'stateB'}}">
Link
</a>