¿Cómo cambio un ng-show en AngularJS basado en un booleano?

113

Tengo un formulario para responder a los mensajes que quiero mostrar solo cuando isReplyFormOpensea ​​verdadero, y cada vez que hago clic en el botón de respuesta, quiero alternar si el formulario se muestra o no. ¿Cómo puedo hacer esto?

liamzebedee
fuente

Respuestas:

218

Solo necesita alternar el valor de "isReplyFormOpen" en el evento ng-click

<a ng-click="isReplyFormOpen = !isReplyFormOpen">Reply</a>
 <div ng-show="isReplyFormOpen" id="replyForm">
   </div>
Nitu Bansal
fuente
Estaba usando exactamente esto, pero por alguna razón el booleano local en ng-click estaba "anulando" el que declaré en el controlador $ scope. El problema desaparece si hago el cambio a través de una función del controlador: ng-click = "toggleBoolean ()". ¿Alguna idea de por qué?
antoine
¿Ha establecido un valor booleano con el valor predeterminado en el controlador? establezca $ scope.isReplyFormOpen = falsel primera vez en la función del controlador e intente.
Nitu Bansal
1
Oh, definí el booleano en el controlador. Lo extraño es que el ng-show leyó correctamente este valor predeterminado al cargar la página, pero luego, después de hacer clic en ng-click, se actualizaría solo este ng-show, y no otros en la página (todos mirando el mismo booleano: al menos en teoría) ...
antoine
3
Resuelto. Debido a que mi ng-click estaba anidado en un ng-repeat, creó un ámbito secundario que oculta el booleano principal cuando intenta cambiar su valor . Consulte stackoverflow.com/questions/15388344/… . De acuerdo con las mejores prácticas de Angular, debe tratar $ scope como directivas de solo lectura.
antoine
Utilizo tu truco con ng-class: <span ng-click="started=!started" ng-class="started ? 'btn-danger' : 'btn-success' ">+1. Gracias :) ♥.
ivahidmontazer
30

Básicamente, lo resolví NO haciendo isReplyFormOpenclic en el valor cada vez que se hace clic en él:

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

<div ng-init="isReplyFormOpen = false" ng-show="isReplyFormOpen" id="replyForm">
    <!-- Form -->
</div>
liamzebedee
fuente
¿Es lo ng-initnecesario?
Charlie Schliesser
6
@CharlieS No es necesario, isReplyFormOpen es undefinedinicialmente y!undefined == true
sceid
17

Si se basa en haga clic aquí, es:

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

Vale la pena señalar que si tiene un botón en el Controlador A y el elemento que desea mostrar en el Controlador B, es posible que deba usar la notación de puntos para acceder a la variable de alcance entre los controladores.

Por ejemplo, esto no funcionará:

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

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

</div>

Para resolver esto, cree una variable global (es decir, en el controlador A o en su controlador principal):

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

Luego agregue un prefijo 'global' a su clic y muestre las variables:

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

Para obtener más detalles, consulte Estados anidados y vistas anidadas en la documentación de Angular-UI , mire un video o lea los alcances de comprensión .

James Gentes
fuente
la mejor solución para booleanos
maverickosama92
0

Aquí hay un ejemplo para usar las directivas ngclick & ng-if.

Nota : ng-if elimina el elemento del DOM, pero ng-hide solo oculta la visualización del elemento.

<!-- <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
fuente
0

Si tiene varios menús con submenús, puede optar por la siguiente solución.

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>

Hay dos funciones que llamé primero: ng-click = hasSubMenu ('tablero'). Esta función se utilizará para alternar el menú y se explica en el código siguiente. El ng-class = "{active: isActive ('/ customerCare / transaction')} agregará una clase activa al elemento del menú actual.

Ahora he definido algunas funciones en mi aplicación:

Primero, agregue una dependencia $ rootScope que se usa para declarar variables y funciones. Para obtener más información sobre $ roootScope, consulte el enlace: https://docs.angularjs.org/api/ng/service/ $ rootScope

Aquí está mi archivo de aplicación:

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

La función anterior se utiliza para agregar una clase activa al elemento de menú actual.

        $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;
            }
        }

De forma predeterminada, $ rootScope.showDash y $ rootScope.showCC se establecen en falso. Establecerá los menús en cerrado cuando la página se cargue inicialmente. Si tiene más de dos submenús, añádalos en consecuencia.

La función hasSubMenu () funcionará para alternar entre los menús. He agregado una pequeña condición

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

permanecerá el submenú abierto después de volver a cargar la página de acuerdo con el elemento de menú seleccionado.

He definido mis páginas como:

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

Puede usar la función isActive () solo si tiene un solo menú sin submenú. Puede modificar el código según sus necesidades. Espero que esto ayude. Que tengas un gran día :)

Vaibhav Ujjwal
fuente