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
}
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
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;
});
Où 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
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
Utiliser le délai d'attente
$timeout(function () { console.log($state.current, 'this is working fine'); }, 100);
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);
});
}
})();
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;
})