web-dev-qa-db-fra.com

Exposer le nom de l'état actuel avec le routeur ui

J'essaie d'implémenter un sélecteur de langue dans lequel, si un utilisateur clique sur "de" dans une page donnée du côté "en" - cela les dirige vers la page du côté "de". Si je console.dir le paramètre $ state, il expose les valeurs que je voudrais avec la propriété "current" de $ state donné. Si j'essaie de console.dir le $ state.current pour me concentrer sur les valeurs que je veux, il ne donne que la propriété d'état parent (mes vues actuelles sont imbriquées).

Ma pensée actuelle est la suivante: je suis sur url/en/content et, dynamiquement, je peux faire en sorte que ma navigation dans les langues charge dynamiquement les points de destination appropriés dans un type d’attribut de données. "go to" et définit ma valeur de langue préférée par angular-translate.

Le problème clé en ce moment est d'exposer ce nom $ state - là encore, lorsque vous parcourez simplement $ state, l'objet actuel donne les valeurs que je veux, mais $ current.state ne donne directement que l'état parent.

Si quelqu'un a une meilleure suggestion sur la façon de procéder (de manière angulaire - pas de fichiers de cookies personnalisés), je suis ravi de prendre des suggestions.

Merci!

Mettre à jour! ÉCHANTILLONS DE CODE:

Référence d'objet de mes états:

var urlStates = {
        en: {
            home: {
                name: 'home',
                url: '/en',
                templateUrl: 'templates/'+lang+'/home.html',
                abstract: 'true'
            },
            home_highlights: {
                name:'home.highlights',
                url: '',
                templateUrl: 'templates/'+lang+'/home.highlights.html'
            },
            home_social:
            {
                name: 'home.social',
                url: '/social',
                templateUrl: 'templates/'+lang+'/home.social.html'
            },
            home_map:
            {
                name: 'home.map',
                url: '/map',
                templateUrl: 'templates/'+lang+'/home.map.html'
            }

        };

Mes états:

$stateProvider
        .state(urlStates.en.home)
        .state(urlStates.en.home_highlights)
        .state(urlStates.en.home_social)
        .state(urlStates.en.home_map);

        $locationProvider.html5Mode(true);

})

Manette:

.controller('LandingPage', function($translate, $state){
    this.state = $state;
    this.greeting = "Hello";
});

Et enfin, la sortie que je vois dans le dom:

Avec this.state = $ state;

{
    "params": {},
    "current": {
        "name": "home.highlights",
        "url": "",
        "templateUrl": "templates/en/home.highlights.html" },
        "transition": null
}

Avec this.state = $ state.current

{
    "name": "",
    "url": "^",
    "views": null,
    "abstract": true
}
44
motleydev

voici comment je le fais

JAVASCRIPT:

var module = angular.module('yourModuleName', ['ui.router']);

module.run( ['$rootScope', '$state', '$stateParams',
                      function ($rootScope,   $state,   $stateParams) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams; 
}
]);

HTML:

<pre id="uiRouterInfo">
      $state = {{$state.current.name}}
      $stateParams = {{$stateParams}}
      $state full url = {{ $state.$current.url.source }}    
</pre>

EXEMPLE 

http://plnkr.co/edit/LGMZnj?p=preview

76
rnrneverdies

Répondre à votre question dans ce format est assez difficile.

D'autre part, vous posez des questions sur la navigation, puis sur l'actuel $state, qui est bizarre.

Pour la première, je dirais que la question est trop large et pour la seconde, je dirais ... eh bien, vous faites quelque chose de mal ou vous manquez l'évidence :)

Prenez le contrôleur suivant:

app.controller('MainCtrl', function($scope, $state) {
  $scope.state = $state;
});

app est configuré comme suit:

app.config(function($stateProvider) {
  $stateProvider
    .state('main', {
        url: '/main',
        templateUrl: 'main.html',
        controller: 'MainCtrl'
    })
    .state('main.thiscontent', {
        url: '/thiscontent',
        templateUrl: 'this.html',
        controller: 'ThisCtrl'
    })
    .state('main.thatcontent', {
        url: '/thatcontent',
        templateUrl: 'that.html'
    });
});

Puis un modèle HTML simple ayant 

<div>
  {{ state | json }}
</div>

Est-ce que "imprimer" par exemple le suivant

{ 
  "params": {}, 
  "current": { 
    "url": "/thatcontent", 
    "templateUrl": "that.html", 
    "name": "main.thatcontent" 
  }, 
  "transition": null
}

J'ai mis en place un petit exemple montrant cela, en utilisant ui.router et pascalprecht.translate pour les menus. J'espère que vous le trouverez utile et que vous découvrirez ce que vous faites de travers.

Plunker ici http://plnkr.co/edit/XIW4ZE

Capture d'écran


imgur

9
Mikko Viitala

Dans mon projet actuel, la solution ressemble à ceci:

J'ai créé un état de langage abstrait

$stateProvider.state('language', {
    abstract: true,
    url: '/:language',
    template: '<div ui-view class="lang-{{language}}"></div>'
});

Chaque état du projet doit dépendre de cet état

$stateProvider.state('language.dashboard', {
    url: '/dashboard'
    //....
});

Les boutons de changement de langue appellent une fonction personnalisée:

<a ng-click="footer.setLanguage('de')">de</a>

Et la fonction correspondante ressemble à ceci (à l'intérieur d'un contrôleur bien sûr):

this.setLanguage = function(lang) {
    FooterLog.log('switch to language', lang);
    $state.go($state.current, { language: lang }, {
        location: true,
        reload: true,
        inherit: true
    }).then(function() {
        FooterLog.log('transition successfull');
    });
};

Cela fonctionne, mais il existe une solution plus intéressante qui consiste simplement à modifier une valeur dans les paramètres d'état à partir de HTML:

<a ui-sref="{ language: 'de' }">de</a>

Malheureusement, cela ne fonctionne pas, voir https://github.com/angular-ui/ui-router/issues/1031

4
paul

Utiliser le délai d'attente

$timeout(function () { console.log($state.current, 'this is working fine'); }, 100);

Voir - https://github.com/angular-ui/ui-router/issues/1627

3
AVI

J'ai entouré $state autour de $timeout et cela a fonctionné pour moi.

Par exemple,

(function() {
  'use strict';

  angular
    .module('app')
    .controller('BodyController', BodyController);

  BodyController.$inject = ['$state', '$timeout'];

  /* @ngInject */
  function BodyController($state, $timeout) {
    $timeout(function(){
      console.log($state.current);
    });

  }
})();
1
poke19962008

C'est juste à cause du temps de charge angulaire qu'il faut pour vous donner l'état actuel.

Si vous essayez d'obtenir l'état actuel en utilisant la fonction $timeout, vous obtiendrez un résultat correct en $state.current.name

$timeout(function(){
    $rootScope.currState = $state.current.name;
})
0
Gaurav Aggarwal