web-dev-qa-db-fra.com

Comment ng-hide et ng-show en utilisant un routeur d'interface utilisateur angulaire?

Imaginez qu'une application possède une page de liste, telle qu'un tableau affichant une liste d'utilisateurs. Il y a un bouton sur chaque ligne du tableau appelé "Modifier", et lorsque vous cliquez dessus, un panneau de droite apparaît à droite du navigateur avec le formulaire permettant de modifier le contenu de cet utilisateur. Lorsque le formulaire est enregistré ou est fermé, le panneau de droite disparaît.

Comment obtenez-vous Angular UI Router pour afficher/masquer automatiquement le panneau de droite lorsque l'état d'édition est entré et quitté? Par défaut, le modèle sera ajouté et supprimé, mais le conteneur lui-même existera toujours à l'écran.

Dans l'application de démonstration pour UI Router, la disposition html avait un espace vide alloué à tous les états enfants, mais dans l'application en construction, j'aimerais vraiment masquer les panneaux s'ils ne sont pas utilisés et même insérer des écrans entiers dans -et-out lorsque les états sont entrés et sortis. Je suppose que je vais devoir utiliser ng-show et ng-hide pour le faire. Comment puis-je m'y prendre avec le routeur d'interface utilisateur?

Merci!

35
egervari

La meilleure solution que j'ai trouvée ressemblait à ceci:

<div id="rightView" ng-show="$state.current.name === 'adminCompanies.list.edit'">
    <div ui-view autoscroll="false"></div>
</div>
34
egervari

Le routeur ui d'Angular offre une méthode propre pour basculer les vues imbriquées.

Commencez par injecter $ state dans votre contrôleur hypothétique de "page de liste". Puis exposez-le à la portée locale $:

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

La variable $ state que nous avons injectée utilise la méthode de Nice "includes". $ state.includes () prend une chaîne en tant qu'argument et la compare au nom de l'état actuel. Il renvoie true si le nom de l'état correspond à la chaîne et false sinon. Cela le rend très agréable à utiliser avec ng-show ou ng-hide.

Utilisez $ state.includes () de ui-router à la place avec le même modèle que egervari:

<div id="rightView" ng-show="$state.includes('list.edit')">
    <div ui-view="edit" autoscroll="false"></div>
</div> 

Outre le passage à la méthode includes, j'ai également ajouté un nom unique à l'attribut ui-view. Vous aurez envie de nommer vos points de vue une fois que vous en avez plus, comme deux. Cela facilitera leur suivi dans vos modèles et votre logique.

Pour ajouter des noms à vos vues. Changer 1 en 2:

// 1
.state('list.edit', {
    url: 'list/edit/:id',
    templateUrl: 'template/edit.html',
    controller: 'ListPageEditCtrl'
})

// 2
.state('list.edit', {
    url: 'list/edit/:id',
    views: {
        'edit': { // this is the unique name you can reference later
            templateUrl: 'template/edit.html',
            controller: 'ListPageEditCtrl'
        }
    }
});
42
Tyler Buchea

Quelle que soit la façon dont vous résolvez ce problème, assurez-vous simplement que, dans la section .run de l'application angulaire, vous déclarez quelque chose comme ceci:

angular.module('yourApp', ['ui.router'])

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

Sinon, ni $ state, ni $ stateParams ne seront accessibles à partir des modèles internes. Je l'ai compris en lisant les documents de ui-router et en vérifiant le code de l'exemple d'application, juste après me cogner la tête contre le clavier car cela ne fonctionnait pas.

2
JSantaCL

Votre URL doit refléter le mode d'état à l'aide de la chaîne de requête: /stuff/1?edit ou /stuff/1 qui correspond à /stuff/1?view.

Vous pouvez utiliser reloadOnSearch=false pour indiquer à AngularJS de ne pas recharger la vue:

http://docs.angularjs.org/api/ngRoute.$routeProvider

Dans votre controller, vérifiez le mode d’état (view ou edit) en utilisant $routeParams. Attrapez l'événement de modification du clic, transmettez votre modèle à votre barre et basculez sa visibilité en conséquence.

Voir ces liens intéressants:

Pouvez-vous changer de chemin sans recharger le contrôleur dans AngularJS?

Mise à jour de l'URL dans Angular JS sans affichage du rendu du rendu

0
roland