Comment basculer un ng-show dans AngularJS basé sur un booléen?

113

J'ai un formulaire pour répondre aux messages que je souhaite afficher uniquement lorsque isReplyFormOpenest vrai, et chaque fois que je clique sur le bouton de réponse, je veux basculer si le formulaire est affiché ou non. Comment puis-je faire ceci?

liamzebedee
la source

Réponses:

218

Il vous suffit de basculer la valeur de "isReplyFormOpen" sur l'événement ng-click

<a ng-click="isReplyFormOpen = !isReplyFormOpen">Reply</a>
 <div ng-show="isReplyFormOpen" id="replyForm">
   </div>
Nitu Bansal
la source
J'utilisais exactement cela, mais pour une raison quelconque, le booléen local dans ng-click "remplaçait" celui que j'avais déclaré dans le contrôleur $ scope. Le problème disparaît si je fais la bascule via une fonction du contrôleur: ng-click = "toggleBoolean ()". Une idée pourquoi?
antoine
avez-vous défini la valeur booléenne par défaut dans le contrôleur? set $ scope.isReplyFormOpen = falsel pour la première fois dans la fonction du contrôleur et essayez.
Nitu Bansal
1
Oh, j'ai défini le booléen dans le contrôleur. Ce qui est étrange, c'est que cette valeur par défaut a été lue correctement par le ng-show lors du chargement de la page, mais après avoir cliqué sur ng-click, il mettrait à jour uniquement ce ng-show, et pas les autres dans la page (tous regardent le même booléen— au moins en théorie) ...
antoine
3
Résolu. Comme mon ng-click était imbriqué dans un ng-repeat, il a créé une portée enfant qui masque le booléen parent lorsque vous essayez de modifier sa valeur . Voir stackoverflow.com/questions/15388344/… . Selon les meilleures pratiques Angular, vous devez traiter $ scope comme des directives en lecture seule.
antoine
J'utilise votre astuce avec ng-class: <span ng-click="started=!started" ng-class="started ? 'btn-danger' : 'btn-success' ">+1. Merci:) ♥.
ivahidmontazer
30

Fondamentalement, je l'ai résolu en NE PAS -ing la isReplyFormOpenvaleur chaque fois qu'il est cliqué:

<a ng-click="isReplyFormOpen = !isReplyFormOpen">Reply</a>

<div ng-init="isReplyFormOpen = false" ng-show="isReplyFormOpen" id="replyForm">
    <!-- Form -->
</div>
liamzebedee
la source
Est-ce que c'est ng-initnécessaire?
Charlie Schliesser
6
@CharlieS Pas nécessaire, isReplyFormOpen est undefinedinitialement et!undefined == true
sceid
17

Si basé sur cliquez ici, c'est:

ng-click="orderReverse = orderReverse ? false : true"
Andrii Motsyk
la source
5

Il est à noter que si vous avez un bouton dans le contrôleur A et l'élément que vous souhaitez afficher dans le contrôleur B, vous devrez peut-être utiliser la notation par points pour accéder à la variable de portée entre les contrôleurs.

Par exemple, cela ne fonctionnera pas :

<div ng-controller="ControllerA">
  <a ng-click="isReplyFormOpen = !isReplyFormOpen">Reply</a>

  <div ng-controller="ControllerB">
    <div ng-show="isReplyFormOpen" id="replyForm">
    </div>
  </div>

</div>

Pour résoudre ce problème, créez une variable globale (c'est-à-dire dans le contrôleur A ou votre contrôleur principal):

.controller('ControllerA', function ($scope) {
  $scope.global = {};
}

Ajoutez ensuite un préfixe `` global '' à vos variables de clic et d'affichage:

<div ng-controller="ControllerA">
  <a ng-click="global.isReplyFormOpen = !global.isReplyFormOpen">Reply</a>

  <div ng-controller="ControllerB">
    <div ng-show="global.isReplyFormOpen" id="replyForm">
    </div>
  </div>

</div>

Pour plus de détails, consultez les États imbriqués et les vues imbriquées dans la documentation Angular-UI , regardez une vidéo ou lisez la compréhension des portées .

James Gentes
la source
meilleure solution pour les booléens
maverickosama92
0

Voici un exemple d'utilisation des directives ngclick & ng-if.

Remarque : que ng-if supprime l'élément du DOM, mais ng-hide masque juste l'affichage de l'élément.

<!-- <input type="checkbox" ng-model="hideShow" ng-init="hideShow = false"></input> -->

<input type = "button" value = "Add Book"ng-click="hideShow=(hideShow ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "bookController" ng-if="hideShow">
             Enter book name: <input type = "text" ng-model = "book.name"><br>
             Enter book category: <input type = "text" ng-model = "book.category"><br>
             Enter book price: <input type = "text" ng-model = "book.price"><br>
             Enter book author: <input type = "text" ng-model = "book.author"><br>


             You are entering book: {{book.bookDetails()}}
     </div>

    <script>
             var mainApp = angular.module("mainApp", []);

             mainApp.controller('bookController', function($scope) {
                $scope.book = {
                   name: "",
                   category: "",
                   price:"",
                   author: "",


                   bookDetails: function() {
                      var bookObject;
                      bookObject = $scope.book;
                      return "Book name: " + bookObject.name +  '\n' + "Book category: " + bookObject.category + "  \n" + "Book price: " + bookObject.price + "  \n" + "Book Author: " + bookObject.author;
                   }

                };
             });
    </script>
Abdallah Okasha
la source
0

Si vous avez plusieurs menus avec sous-menus, vous pouvez utiliser la solution ci-dessous.

HTML

          <ul class="sidebar-menu" id="nav-accordion">
             <li class="sub-menu">
                  <a href="" ng-click="hasSubMenu('dashboard')">
                      <i class="fa fa-book"></i>
                      <span>Dashboard</span>
                      <i class="fa fa-angle-right pull-right"></i>
                  </a>
                  <ul class="sub" ng-show="showDash">
                      <li><a ng-class="{ active: isActive('/dashboard/loan')}" href="#/dashboard/loan">Loan</a></li>
                      <li><a ng-class="{ active: isActive('/dashboard/recovery')}" href="#/dashboard/recovery">Recovery</a></li>
                  </ul>
              </li>
              <li class="sub-menu">
                  <a href="" ng-click="hasSubMenu('customerCare')">
                      <i class="fa fa-book"></i>
                      <span>Customer Care</span>
                      <i class="fa fa-angle-right pull-right"></i>
                  </a>
                  <ul class="sub" ng-show="showCC">
                      <li><a ng-class="{ active: isActive('/customerCare/eligibility')}" href="#/CC/eligibility">Eligibility</a></li>
                      <li><a ng-class="{ active: isActive('/customerCare/transaction')}" href="#/CC/transaction">Transaction</a></li>
                  </ul>
              </li>
          </ul>

Il y a deux fonctions que j'ai appelées en premier: ng-click = hasSubMenu ('dashboard'). Cette fonction sera utilisée pour basculer le menu et elle est expliquée dans le code ci-dessous. Le ng-class = "{active: isActive ('/ customerCare / transaction')} il ajoutera une classe active à l'élément de menu actuel.

Maintenant, j'ai défini certaines fonctions dans mon application:

Tout d'abord, ajoutez une dépendance $ rootScope qui est utilisée pour déclarer des variables et des fonctions. Pour en savoir plus sur $ roootScope, consultez le lien: https://docs.angularjs.org/api/ng/service/ $ rootScope

Voici mon fichier d'application:

 $rootScope.isActive = function (viewLocation) { 
                return viewLocation === $location.path();
        };

La fonction ci-dessus est utilisée pour ajouter une classe active à l'élément de menu actuel.

        $rootScope.showDash = false;
        $rootScope.showCC = false;

        var location = $location.url().split('/');

        if(location[1] == 'customerCare'){
            $rootScope.showCC = true;
        }
        else if(location[1]=='dashboard'){
            $rootScope.showDash = true;
        }

        $rootScope.hasSubMenu = function(menuType){
            if(menuType=='dashboard'){
                $rootScope.showCC = false;
                $rootScope.showDash = $rootScope.showDash === false ? true: false;
            }
            else if(menuType=='customerCare'){
                $rootScope.showDash = false;
                $rootScope.showCC = $rootScope.showCC === false ? true: false;
            }
        }

Par défaut, $ rootScope.showDash et $ rootScope.showCC sont définis sur false. Cela mettra les menus fermés lors du chargement initial de la page. Si vous avez plus de deux sous-menus, ajoutez en conséquence.

La fonction hasSubMenu () fonctionnera pour basculer entre les menus. J'ai ajouté une petite condition

if(location[1] == 'customerCare'){
                $rootScope.showCC = true;
            }
            else if(location[1]=='dashboard'){
                $rootScope.showDash = true;
            }

il restera le sous-menu ouvert après le rechargement de la page en fonction de l'élément de menu sélectionné.

J'ai défini mes pages comme:

$routeProvider
        .when('/dasboard/loan', {
            controller: 'LoanController',
            templateUrl: './views/loan/view.html',
            controllerAs: 'vm'
        })

Vous ne pouvez utiliser la fonction isActive () que si vous avez un seul menu sans sous-menu. Vous pouvez modifier le code selon vos besoins. J'espère que cela aidera. Passez une bonne journée :)

Vaibhav Ujjwal
la source