Search code examples
angularjsangularjs-scopeangularjs-filterangularjs-ng-click

Ng-click filter between 2 scopes


I am new to Angular.js so I am not sure if this is the right approach. I have two scopes that are used to display 2 sets of buttons. The second set should be dependent on the button I click in the first set.

<!-- Insulation placement -->
  $rootScope.roofs = [
    { 
      type: 'roof',
      label: 'Pitched Roof'
    },
    { 
      type: 'attic',
      label: 'Floor of Attic' 
    }
  ];


<!-- Roof insulation types -->
  $rootScope.roofInsulation = [
    { 
      target: 'roof',
      type: 'between_rafters',
      label: 'Between Rafters'
    },
    { 
      target: 'roof',
      type: 'between_rafters_counter_batten',
      label: 'Between Rafters With A Counter Batten' 
    },
    { 
      target: 'roof',
      type: 'between_rafters_calibel',
      label: 'Between Rafters With Calibel' 
    },
    { 
      target: 'roof',
      type: 'between_rafters_thermal_laminate',
      label: 'Between Rafters With Thermal Laminate' 
    },
    { 
      target: 'attic',
      type: 'test',
      label: 'Test'
    }
  ];

and my HTML

<div ng-repeat="types in roofs">

    <button ng-click="myFilter = {target: '{{types.type}}'}" class="btn btn-primary" type="button">{{types.label}}</button>

</div>

<div>

  <button ng-repeat="variants in roofInsulation | filter: myFilter" class="btn btn-secondary" type="button">{{variants.label}}</button>

</div>

I realize that myFilter in the ng-click is a bit of a hack, but aside from that I can't get it to filter the results of ng-repeat. The myFilter variable does return the proper result {target: 'roof'} (for the first button). Do I assume correctly that it's because the first set of buttons is in a different scope than the second one?


Solution

  • You are not really using 2 different scopes here. If you had been using 2 different controllers or different directives then you would have got 2 different scopes. You are using $rootScope which is common across the entire angular app.

    The reason myFilter is not working is because angular is unable to parse the expression in ng-click correctly, it's better you write a method (exposed to the scope) and change the value of myFilter in the method. It's a good practice as well as a better way to achieve what you are trying to do.

    HTML

    <button ng-click="setFilter(types)" class="btn btn-primary" type="button">{{types.label}}</button>
    

    JS

    $rootScope.setFilter = function(types) {
        $rootScope.myFilter = {target: types.type};
    }
    

    Check this fiddle here, I have created a working example based on your code.

    EDIT

    Even if your target variable is an array there shouldn't be any issue because Anguar's pipe filter will take care of it. I have updated and created a new fiddle to show it, check it here.

    So if target is an array having 2 values - ['roof', 'attic'], that particular element will be shown for both the buttons.