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>
72
demandé sur theDmi 2014-06-22 13:03:20

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: -)

63
répondu RavenHursT 2015-03-24 20:26:54

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

61
répondu Radim Köhler 2015-05-05 17:05:44

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.

19
répondu Fabio Picheli 2017-03-02 13:06:33

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

2
répondu codepushr 2016-02-07 13:48:36

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);
            });
        }
    };
}
2
répondu Linvi 2016-07-27 15:35:47

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.

1
répondu ilter 2015-04-26 00:45:53

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&param2'
    templateUrl: 'wizard.html',
    controller: 'Controller as ctrl'
});
1
répondu rynangeles 2016-06-21 00:29:13

c'est simplement de travailler pour moi

dans le contrôleur

$scope.createState = 'stateName';

en vue

ui-sref="{{ createState }}"
0
répondu Abou-Emish 2016-02-25 15:32:37

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&param2&param3',
            templateUrl: 'MyPage.html',
            controller: 'MyCtrl'
          });

Profitez-en !

0
répondu Emidomh 2016-05-20 13:04:12
<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.

0
répondu Ryan Augustine 2017-11-17 06:43:28
<a ng-click="{{getLinkUrl({someParam: someValue})}}">Dynamic Link</a>

$scope.getLinkUrl = function(value){
  $state.go('My.State',{someParam:value});

}

il retourne un objet

0
répondu bklups 2018-03-20 13:10:10

ou quelque chose comme ça:

<a ui-sref="{{ condition ? 'stateA' : 'stateB'}}">
  Link
</a>
-1
répondu Karens 2016-02-29 12:08:57