Como alterno um ng-show no AngularJS com base em um booleano?

113

Tenho um formulário para responder a mensagens que desejo mostrar apenas quando isReplyFormOpenfor verdadeiro e, sempre que clico no botão de resposta, quero alternar se o formulário é mostrado ou não. Como posso fazer isso?

liamzebedee
fonte

Respostas:

218

Você só precisa alternar o valor de "isReplyFormOpen" no evento ng-click

<a ng-click="isReplyFormOpen = !isReplyFormOpen">Reply</a>
 <div ng-show="isReplyFormOpen" id="replyForm">
   </div>
Nitu Bansal
fonte
Eu estava usando exatamente isso, mas por alguma razão o booleano local no ng-click estava "sobrescrevendo" aquele que declarei no escopo $ do controlador. O problema desaparece se eu alternar por meio de uma função do controlador: ng-click = "toggleBoolean ()". Alguma ideia do porquê?
antoine
você definiu o valor booleano com o padrão no controlador? defina $ scope.isReplyFormOpen = falsel pela primeira vez na função do controlador.e tente.
Nitu Bansal
1
Oh, eu defini o booleano no controlador. O estranho é que este valor padrão foi lido corretamente pelo ng-show no carregamento da página, mas depois de clicar em ng-click, ele atualizaria apenas este ng-show, e não outros na página (todos assistindo ao mesmo Booleano— pelo menos em teoria) ...
antoine
3
Resolvi-o. Como meu ng-click estava aninhado em uma ng-repeat, ele criou um escopo filho que oculta o Booleano pai quando você tenta alterar seu valor . Consulte stackoverflow.com/questions/15388344/… . De acordo com as práticas recomendadas do Angular, você deve tratar $ scope como somente leitura nas diretivas.
antoine
Eu uso seu truque com ng-class: <span ng-click="started=!started" ng-class="started ? 'btn-danger' : 'btn-success' ">+1. Obrigado:) ♥.
ivahidmontazer de
30

Basicamente, resolvi NÃO clicando no isReplyFormOpenvalor sempre que ele é clicado:

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

<div ng-init="isReplyFormOpen = false" ng-show="isReplyFormOpen" id="replyForm">
    <!-- Form -->
</div>
liamzebedee
fonte
É o ng-initnecessário?
Charlie Schliesser
6
@CharlieS Não é necessário, isReplyFormOpen é undefinedinicialmente e!undefined == true
sceid
17

Se baseado em clique aqui é:

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

É importante notar que se você tiver um botão no Controlador A e o elemento que deseja mostrar no Controlador B, pode ser necessário usar a notação de ponto para acessar a variável de escopo entre os controladores.

Por exemplo, isso não 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 isso, crie uma variável global (ou seja, no Controlador A ou no seu Controlador principal):

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

Em seguida, adicione um prefixo 'global' ao seu clique e mostre as variáveis:

<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 obter mais detalhes, verifique os Estados aninhados e visualizações aninhadas na documentação da IU Angular , assista a um vídeo ou leia os escopos de compreensão .

James Gentes
fonte
melhor solução para booleanos
maverickosama92
0

Aqui está um exemplo para usar as diretivas ngclick & ng-if.

Nota : que ng-if remove o elemento do DOM, mas ng-hide apenas oculta a exibição do 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
fonte
0

Se você tiver vários menus com submenus, poderá usar a solução abaixo.

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>

Há duas funções que chamei primeiro: ng-click = hasSubMenu ('painel'). Esta função será utilizada para alternar o menu e é explicada no código abaixo. O ng-class = "{active: isActive ('/ customerCare / transaction')} irá adicionar uma classe ativa ao item de menu atual.

Agora defini algumas funções em meu aplicativo:

Primeiro, adicione uma dependência $ rootScope que é usada para declarar variáveis ​​e funções. Para saber mais sobre $ roootScope, consulte o link: https://docs.angularjs.org/api/ng/service/ $ rootScope

Aqui está meu arquivo de aplicativo:

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

A função acima é usada para adicionar uma classe ativa ao item de menu atual.

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

Por padrão, $ rootScope.showDash e $ rootScope.showCC são definidos como falsos. Isso definirá os menus para fechados quando a página for carregada inicialmente. Se você tiver mais de dois submenus, adicione de acordo.

A função hasSubMenu () funcionará para alternar entre os menus. Eu adicionei uma pequena condição

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

ele permanecerá o submenu aberto após recarregar a página de acordo com o item de menu selecionado.

Eu defini minhas páginas como:

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

Você pode usar a função isActive () apenas se tiver um único menu sem submenu. Você pode modificar o código de acordo com sua necessidade. Espero que isso ajude. Tenha um ótimo dia :)

Vaibhav Ujjwal
fonte