Search code examples
angularjsangularjs-scope

How do I reference and set all scope variables created from ng-click within ng-repeat?


I want to be able to hide the item.value when I click on item.label or just hide everything with I click on the button. I'm not too sure how the "hide" variables are related here. From what I understand, they are created separately in an isolated scope so my button should not work. What is the solution here?

<button ng-click="hide=false">HideAll</button>
<div ng-repeat="item in items">
     <div ng-click="hide=!hide">item.label</div>
     <div ng-hide="hide">item.value</div>
</div>

Solution

  • You should be using the dot syntax and within each item model, you can use your toggle button to toggle the hide property of each individual item. This way you can ng-hide each item via item.hide expression.

    Angular's ng-hide directive creates a watch on the expression. When the value of the evaluated expression changes, it triggers a change to the DOM to show (if the value is falsey) or hide (if the value is not falsey). Initially, the items array does not have the hide property set, so they are all undefined, which evaluates to a falsey value, thus the items do not hide by default on initial display. Once an item's hide property is set (either by using the ng-click expression to execute the controller's toggleHide method or the controller's hideAll method).

    These are some of the basics of angular expressions and core ng directives.

    angular.module('myApp', [])
      .controller('MainController', function () {
        this.$onInit = function $onInit() {    
          this.items = [
            {value: 'Item 1'},
            {value: 'Item 2'},
            {value: 'Item 3'}
          ];
        };
        
        this.toggleHide = function toggleHide(item) {
          item.hide = !item.hide;
        };
        
        this.hideAll = function hideAll() {
          var items = this.items;
          for (var i = 0; i < items.length; ++i) {
            items[i].hide = true;
          }
        };
      });
    <script src="//code.angularjs.org/1.6.5/angular.js"></script>
    <div ng-app="myApp" ng-controller="MainController as mc">
      <button ng-click="mc.hideAll()">Hide All</button>
      <div ng-repeat="item in mc.items">
        <div><button ng-click="mc.toggleHide(item)">Toggle</button></div>
        <div ng-hide="item.hide">{{::item.value}}</div>
      </div>
    </div>

    This answer is leveraging some features of the more recent versions of angular 1.x (controller lifecycle methods and one time binding -- none of which are shipped with the stackoverflow snippet of Angular 1.2).