start - Establezca dinĂ¡micamente el valor de ui-sref Angularjs
ui-router angular 6 (12)
Después de probar varias soluciones, encontré el problema en el código angular.ui.router
.
El problema proviene del hecho de que el método de update
ui.router se desencadena con ref.state
que significa que no es posible actualizar el valor de la href
utilizada cuando se hace clic en el elemento.
Aquí hay 2 soluciones para resolver el problema:
Directiva personalizada
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();
}
};
});
El HTML para usar es bastante simple:
<a dynamic-sref="home.mystate"
dynamic-sref-params="{ param1 : scopeParam }">
Link
</a>
Repare el código de ui.router:
En angular.router.js encontrará la directiva $StateRefDirective
(línea 4238 para la versión 0.3).
Cambiar el código de la directiva a:
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);
});
}
};
}
He buscado una pregunta similar, pero las que surgieron parecen ligeramente diferentes. Estoy tratando de cambiar el ui-sref = '''' de un enlace de forma dinámica (este enlace apunta a la siguiente sección de un formulario de asistente y la siguiente sección depende de la selección realizada en la lista desplegable). Simplemente intento establecer el atributo ui-sref dependiendo de alguna selección en un cuadro de selección. Puedo cambiar el ui-sref al enlazar a un atributo de alcance que se establece cuando se realiza una selección. sin embargo, el enlace no funciona, ¿es esto posible? Gracias
<a ui-sref="form.{{url}}" >Next Section</a>
y luego en mi controlador, configuré el parámetro url de esta manera
switch (option) {
case ''A'': {
$scope.url = ''sectionA'';
} break;
case ''B'': {
$scope.url = ''sectionB'';
} break;
}
Alternativamente, utilicé directivas para que funcione generando el hipervínculo con el atributo ui-sref deseado según la opción seleccionada en el cuadro de selección (menú desplegable).
Sin embargo, esto significa que tengo que volver a crear el enlace cada vez que se selecciona una opción diferente de la casilla de selección, lo que provoca un efecto de parpadeo indeseable. Mi pregunta es: ¿es posible cambiar el valor de ui-sref como he intentado hacer lo anterior al cambiar el valor de url en mi controlador o tengo que volver a crear todo el elemento usando una directiva cada vez que selecciono un ui-sref? se hace como he hecho a continuación? (simplemente mostrando esto para completar)
Seleccione la directiva de opción (esta directiva genera la directiva de enlace)
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);
})
}
}
})
Directiva de hipervínculo
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) { }
}
})
Plantilla de hipervínculo
<div>
<button ui-sref="form.{url}}">Next Section</button>
</div>
Eche un vistazo en este número #2944 .
El ui-sref
no mira la expresión de estado, puede usar ui-state
y ui-state-params
pasando la variable.
<a data-ui-state="selectedState.state" data-ui-state-params="{''myParam'':aMyParam}">
Link to page {{selectedState.name}} with myParam = {{aMyParam}}
</a>
También una demo rápida provista en el boleto.
El mejor enfoque es hacer uso de uiRouter''s $state.go(''stateName'', {params})
de uiRouter''s $state.go(''stateName'', {params})
directiva ng-click
. Y deshabilite el botón si no se selecciona ninguna opción.
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>
Controlador
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 || {});
}
};
}
Estado
$stateProvider.state(''wizard'', {
url: ''/wizard/:param1/:param2'', // or ''/wizard?param1¶m2''
templateUrl: ''wizard.html'',
controller: ''Controller as ctrl''
});
Hay un plunker de trabajo . La forma más fácil parece ser la combinación de:
Estos juntos podrían usarse como:
<a ng-href="{{$state.href(myStateName, myParams)}}">
Entonces, (siguiendo este plunker ) tener estados como estos:
$stateProvider
.state(''home'', {
url: "/home",
...
})
.state(''parent'', {
url: "/parent?param",
...
})
.state(''parent.child'', {
url: "/child",
...
Podemos cambiar estos valores para generar dinámicamente el href
<input ng-model="myStateName" />
<input ng-model="myParams.param" />
Verifíquelo en acción aquí
ORIGINAL:
Hay un ejemplo práctico de cómo lograr lo que necesitamos. Pero no con ui-sref
dinámico.
Como podemos, podemos verificar aquí: https://github.com/angular-ui/ui-router/issues/395
P: [A] los atributos re-ui-sref dinámicos no son compatibles?
A: Correcto.
Pero podemos usar diferentes funciones de ui-router
: [$state.go("statename")][5]
Entonces, esta podría ser la cosa del controlador:
$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);
};
Y aquí está la plantilla 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>
El ejemplo de trabajo
NOTA: hay un enlace más actualizado a la definición de here , pero el obsoleto es un poco más claro para mí
Me las arreglé para implementarlo de esta forma (sin embargo, estoy usando la variante de controllerAs, no a través de $ scope).
Modelo
<button ui-sref="main({ i18n: ''{{ ctrlAs.locale }}'' })">Home</button>
Controlador
var vm = this;
vm.locale = ''en''; // or whatever dynamic value you prepare
También vea la documentación en ui-sref
donde puede pasar los parámetros:
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
O simplemente algo como esto:
<a ui-sref="{{ condition ? ''stateA'' : ''stateB''}}">
Link
</a>
Para gestionar múltiples parámetros dinámicos usando ui-sref, aquí mi solución:
Html: (''MiPágina.html'')
<button type="button" ui-sref="myState(configParams())">
Controlador: (''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''
});
¡Disfruta!
Parece que esto es posible después de todo.
Una ruta de GitHub en GitHub por uno de los autores de ui-enrutador me llevó a probar lo siguiente:
<a ng-href="{{getLinkUrl()}}">Dynamic Link</a>
Luego, en tu controlador:
$scope.getLinkUrl = function(){
return $state.href(''state-name'', {someParam: $scope.someValue});
};
Resulta que esto funciona como un encanto con valores de ámbito variable y todo. Incluso puede hacer que la referencia constante de la cadena ''state-name'' sea un valor delimitado y eso también actualizará la href en la vista :-)
Vine a responder eso para siempre :)
Afortunadamente, no necesita usar un botón para hacer clic ng , o usar una función dentro de ng-href para lograr lo que busca. En lugar;
Puede crear una var $scope
en su controlador y asignarle la cadena ui-sref
y usarla en su vista, como atributo ui-sref
.
Me gusta esto:
// 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>
Eso funciona perfectamente para mí.
esto solo me funciona
en el controlador
$scope.createState = ''stateName'';
en vista
ui-sref="{{ createState }}"
<a ng-click="{{getLinkUrl({someParam: someValue})}}">Dynamic Link</a>
$scope.getLinkUrl = function(value){
$state.go(''My.State'',{someParam:value});
}
Devuelve un objeto
<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 alguien solo quiere establecer dinámicamente los $ stateParams de ui-sref en Angularjs. Nota: En el elemento de inspección, seguirá apareciendo como "comprar ({myPairIndex: $ index})" pero el índice $ se recuperará en ese estado.