Search code examples
javascripthtmlangularjsangularjs-scope

Can I use ng-repeat and have isolated scope with angular component?


So I have a ng repeat block that passes an object to a angular component. That looks like this

<div ng-repeat="assessor in $ctrl.dedupeDetail.matches">
    <assessordedupequickcard assessor="assessor"></assessordedupequickcard>
</div>

Edit:

I thought it might be helpful to add what the component is defined as. Here is that code

angular.module('assessor.dedupe')
    .component('assessordedupequickcard', {
        controller: 'assessorDedupeQuickcardController',
        templateUrl: 'src/app/assessor/dedupe/quickcard/assessor.dedupe.quickcard.html',
        bindings: {
            assessor: '<',
        }
    });

End Edit

The quickcard takes the various fields in the assessor object such as name, address, phone numbers, age, etc, and displays them cleanly in a small box that is supposed to represent a contact card for that person.

In that quickcard are two labels

<label ng-if="$ctrl.isSource" class="quickcard-list-header pull-right">FROM</label>
<label ng-if="$ctrl.isTarget" class="quickcard-list-header pull-right">TO</label>

In the view where the list of these, "contact cards" is displayed there is a functionality where you can select one card, then select another, and transfer information from one to the other.

When selecting the first

<assessordedupequickcard assessor="assessor"></assessordedupequickcard>

from the ng-repeated list I need to flip a flag that exists within that < assessordedupequickcard > component's scope in its controller and flip isSource = true.

And when selecting the second

<assessordedupequickcard assessor="assessor"></assessordedupequickcard>

from the ng-repeated list, again move one layer deeper into that custom component's controller and flip its isTarget = true.

But I cannot figure out how to isolate which component will have a flag flip. Because they are not individually named they are all treated as one. Any change I make to one of the repeated custom components happens to all of the custom components.

I'm not sure I've explained this well, if there's any more info I can provide please let me know. Thanks in advance for any help anyone can provide me in regards to this.


Solution

  • Angular components always have isolated scope (components documentation). Now, you just need to implement two-way binding and pass the data object. This makes the controller (that contains repeated components) aware of any data changes occurring within each components distinctly.

    Page HTML:

    <div ng-controller="SampleCtrl">
      <h3>Repeated Components with Isolated Scope: </h3>
      <box ng-repeat="data in collection track by $index" data="data"></box>
    
      <h3>Parent Controller:</h3>
      <pre>{{collection| json}}</pre>
    </div>
    

    Page JS:

    .controller('SampleCtrl', function($scope) {
      $scope.collection = [{
        name: 'A'
      }, {
        name: 'B'
      }, {
        name: 'C'
      }, {
        name: 'D'
      }, {
        name: 'E'
      }];
    
    })
    

    Component JS:

    .component('box', {
        bindings: {
          data: '=?'
        },
        templateUrl: 'box.html',
        controllerAs: 'vm',
        controller: function() {
          var vm = this;
          vm.toggle = function() {
            vm.data.flagged = !vm.data.flagged;
          }
        }
      });
    

    Component HTML:

    <div class="box" ng-click="vm.toggle()">
      <p>{{vm.data}}</p>
    </div>
    

    Plunker Demo