Définir dynamiquement la valeur de ui-sref Angularjs
j'ai cherché une question similaire mais celles qui sont apparues semblent légèrement différentes. Je suis en train de changer l'interface utilisateur-sref=" un lien dynamique (ce lien pointe vers la section suivante de l'assistant formulaire et la section suivante dépend de la sélection effectuée dans la liste déroulante). J'essaie simplement de définir l'attribut ui-sref en fonction d'une sélection dans une boîte de sélection. Je peux modifier l'ui-sref en me liant à un attribut scope qui est défini lorsqu'une sélection est faite. cependant le lien ne fonctionne pas, est-ce possible? merci
<a ui-sref="form.{{url}}" >Next Section</a>
et puis dans mon controller, je mets le paramètre url de cette façon
switch (option) {
case 'A': {
$scope.url = 'sectionA';
} break;
case 'B': {
$scope.url = 'sectionB';
} break;
}
alternativement, j'ai utilisé des directives pour le faire fonctionner en générant l'hyperlien avec l'attribut ui-sref désiré selon l'option sélectionnée sur la boîte de sélection (drop down).
Hhowever cela signifie que je dois recréer le lien chaque fois qu'une option différente est sélectionnée de la selectbox qui provoque un effet de scintillement indésirable. Ma question Est la suivante: est-il possible de changer la valeur de l'ui-sref comme j'ai essayé de le faire ci-dessus en modifiant simplement la valeur de l'url dans mon contrôleur ou dois-je recréer l'élément entier en utilisant une directive chaque fois qu'une sélection est faite comme je l'ai fait ci-dessous? (juste indiquant ce à des fins d'exhaustivité)
Select option directive (Cette directive génère la directive link)
define(['app/js/modules/app', 'app/js/directives/hyperLink'], function (app) {
app.directive('selectUsage', function ($compile) {
function createLink(scope,element) {
var newElm = angular.element('<hyper-link></hyper-link>');
var el = $(element).find('.navLink');
$(el).html(newElm);
$compile(newElm)(scope);
}
return {
restrict: 'E',
templateUrl: '/Client/app/templates/directives/select.html'
,link: function (scope, element, attrs) {
createLink(scope, element);
element.on('change', function () {
createLink(scope,element);
})
}
}
})
"1519130920 lien Hypertexte" directive
define(['app/js/modules/app'], function (app) {
app.directive('hyperLink', function () {
return {
restrict: 'E',
templateUrl: '/Client/app/templates/directives/hyperLink.html',
link: function (scope, element, attrs) { }
}
})
"1519130920 lien Hypertexte" modèle
<div>
<button ui-sref="form.{url}}">Next Section</button>
</div>
12 réponses
semble que c'est possible de faire après tout.
Un fil d'ariane sur GitHub par l'un des ui-router les auteurs m'ont amené à essayer ce qui suit:
<a ng-href="{{getLinkUrl()}}">Dynamic Link</a>
puis, dans votre contrôleur:
$scope.getLinkUrl = function(){
return $state.href('state-name', {someParam: $scope.someValue});
};
S'avère, cela fonctionne comme un charme avec Changer les valeurs scoped et tout. Vous pouvez même faire de la constante de chaîne de caractères "state-name" une valeur scopée et qui mettra à jour href dans la vue comme Eh bien: -)
Il y a un travail plunker . La manière la plus facile semble être d'utiliser la combinaison de:
Ces, ensemble, pourraient être utilisés comme:
<a ng-href="{{$state.href(myStateName, myParams)}}">
, (à la suite de ce plunker ) avoir des états comme ceux-ci:
$stateProvider
.state('home', {
url: "/home",
...
})
.state('parent', {
url: "/parent?param",
...
})
.state('parent.child', {
url: "/child",
...
nous pouvons changer ces valeurs pour générer dynamiquement le href
<input ng-model="myStateName" />
<input ng-model="myParams.param" />
archiver action
ORIGINAL:
il y a un exemple pratique comment réalisons ce dont nous avons besoin. Mais pas avec dynamique ui-sref
.
comme nous pouvons le vérifier ici: https://github.com/angular-ui/ui-router/issues/395
Q: [A]re dynamique de l'interface utilisateur-sref les attributs non pris en charge?
Un: Correct.
mais nous pouvons utiliser des caractéristiques différentes de ui-router
: [$state.go("statename")][5]
donc, ce ça pourrait être le truc du contrôleur:
$scope.items = [
{label : 'first', url: 'first'},
{label : 'second', url: 'second'},
{label : 'third', url: 'third'},
];
$scope.selected = $scope.items[0];
$scope.gotoSelected = function(){
$state.go("form." + $scope.selected.url);
};
et voici le modèle HTML:
<div>
choose the url:
<select
ng-model="selected"
ng-options="item.label for item in items"
></select>
<pre>{{selected | json}}</pre>
<br />
go to selected
<button ng-click="gotoSelected()">here</button>
<hr />
<div ui-view=""></div>
</div>
travail exemple
NOTE: il y a plus up to date lien vers $state.aller définition, mais le obsolète est un peu plus clair pour moi
regardez dans ce numéro #2944 .
le ui-sref
ne regarde pas l'expression d'état, vous pouvez utiliser ui-state
et ui-state-params
en passant la variable.
<a data-ui-state="selectedState.state" data-ui-state-params="{'myParam':aMyParam}">
Link to page {{selectedState.name}} with myParam = {{aMyParam}}
</a>
aussi un rapidement Démo fourni dans le billet.
j'ai réussi à l'implémenter de cette façon (j'utilise la variante controllerAs - pas via $scope).
Modèle
<button ui-sref="main({ i18n: '{{ ctrlAs.locale }}' })">Home</button>
contrôleur
var vm = this;
vm.locale = 'en'; // or whatever dynamic value you prepare
Voir aussi la documentation de ui-sref
où vous pouvez passer params:
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
après avoir essayé diverses solutions, j'ai trouvé le problème dans le code angular.ui.router
.
Le problème vient du fait que l'interface utilisateur.la méthode du routeur update
est déclenchée avec le ref.state
ce qui signifie qu'il n'est pas possible de mettre à jour la valeur du href
utilisé lorsque l'élément est cliqué.
voici 2 solutions pour résoudre le problème:
Personnalisé Directive
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();
}
};
});
le HTML pour l'utiliser est assez simple :
<a dynamic-sref="home.mystate"
dynamic-sref-params="{ param1 : scopeParam }">
Link
</a>
Correction de l'interface utilisateur.code du routeur:
en angle.routeur.js your trouvera la directive $StateRefDirective
(ligne 4238 pour la version 0.3).
changer le code de la directive en:
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);
});
}
};
}
est venu répondre que pour de bon :)
heureusement, vous n'avez pas besoin d'utiliser un bouton pour ng-click , ou d'utiliser une fonction à l'intérieur d'un ng-href pour atteindre ce que vous recherchez. Au lieu de cela:
vous pouvez créer un $scope
var dans votre controller et lui assigner la chaîne ui-sref
et l'utiliser dans votre vue, comme attribut ui-sref
.
comme ceci:
// Controller.js
// if you have nasted states, change the index [0] as needed.
// I'm getting the first level state after the root by index [0].
// You can get the child by index [1], and grandchild by [2]
// (if the current state is a child or grandchild, of course).
var page = $state.current.name.split('.')[0];
$scope.goToAddState = page + ".add";
// View.html
<a ui-sref="{{goToAddState}}">Add Button</a>
ça marche parfaitement pour moi.
la meilleure approche est d'utiliser uiRouter's $state.go('stateName', {params})
sur la directive ng-click
de button. Et désactiver le bouton si aucune option n'est sélectionnée.
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>
contrôleur
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 || {});
}
};
}
État
$stateProvider.state('wizard', {
url: '/wizard/:param1/:param2', // or '/wizard?param1¶m2'
templateUrl: 'wizard.html',
controller: 'Controller as ctrl'
});
c'est simplement de travailler pour moi
dans le contrôleur
$scope.createState = 'stateName';
en vue
ui-sref="{{ createState }}"
Pour gérer les plusieurs dynamiques params à l'aide de l'interface utilisateur-sref, voici ma solution :
Html: ('MyPage.html')
<button type="button" ui-sref="myState(configParams())">
Contrôleur: ('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'
});
Profitez-en !
<ul class="dropdown-menu">
<li ng-repeat="myPair in vm.Pairs track by $index">
<a ui-sref="buy({myPairIndex:$index})">
<span class="hidden-sm">{{myPair.pair}}</span>
</a>
</li>
</ul>
si quelqu'un veut seulement régler dynamiquement le $stateParams de ui-sref à Angularjs. Note: dans l'élément inspect, il apparaîtra toujours comme "buy({myPairIndex:$index})" mais $index sera récupéré dans cet état.
<a ng-click="{{getLinkUrl({someParam: someValue})}}">Dynamic Link</a>
$scope.getLinkUrl = function(value){
$state.go('My.State',{someParam:value});
}
il retourne un objet
ou quelque chose comme ça:
<a ui-sref="{{ condition ? 'stateA' : 'stateB'}}">
Link
</a>