otissv
otissv

Reputation: 845

Multiple AngularJS directives with different scopes

Hi I have a two popup directives on the same page. The problem is when I click on one they both pop up.

How can I isolate each scope from each other so only the popup that's clicked pops up?

HTML

<popup class="popup">
  <trigger>
    <a href="#" data-ng-click="showPopup()">Show Popup</a>
  </trigger>
  <pop>
   I popped up
  </pop>
</popup>

<popup class="popup">
  <trigger>
    <a href="#" data-ng-click="showPopup()">Show Popup</a>
  </trigger>
  <pop>
   I popped up too
  </pop>
</popup>

popup.js

angular.module('sembaApp')
  .directive('popup', function () {
    return {
        restrict:  'E',
        replace:    true,
      transclude: true,
      template:   '<div data-ng-transclude></div>',
      controller: function postLink($scope, $element, $attrs) {
        $scope.popup = false;
        $scope.showPopup = function() {
          $scope.popup = !$scope.popup;
        }
      }
    }
  })
  .directive('trigger', function () {
    return {
        require: '^popup',
        restrict:  'E',
        replace:    true,
      transclude: true,
      template:   '<div data-ng-transclude></div>',
    }
  })
  .directive('pop', function () {
    return {
        require: '^popup',
        restrict:  'E',
        replace:    true,
      transclude: true,
      template:   '<aside data-ng-transclude data-ng-show="popup"> yay</aside>'      
    }
  });

Upvotes: 2

Views: 3084

Answers (3)

otissv
otissv

Reputation: 845

Got it working by changing $scope.popup to this.popup

  <popup class="popup"> 
    <a href="#" data-ng-click="showPopup()">Show Popup</a>
    <pop> 
      I popped up
    </pop>
  </popup>

  controller: function postLink($scope, $element, $attrs) {
    this.popup = false;
    $scope.showPopup = function() {
      this.popup = !this.popup;
    }
  }

Upvotes: 0

zs2020
zs2020

Reputation: 54543

It might be a better idea to simplify the directives so the scopes will be easy to handle.

<div ng-app="sembaApp" ng-init="popup1=false;popup2=false;">
    <popup class="popup" ng-model="popup1">
        <pop data-ng-show="popup1">I popped up</pop>
    </popup>
    <popup class="popup" ng-model="popup2">
        <pop data-ng-show="popup2">I popped up too</pop>
    </popup>
</div>

angular.module('sembaApp', [])
    .directive('popup', function () {
    return {
        scope:{
            ngModel: '='
        },
        restrict: 'E',
        replace: true,
        transclude: true,
        template: '<div data-ng-transclude><a href="#" data-ng-click="showPopup()">Show Popup</a></div>',
        link: function postLink($scope, $element, $attrs) {
            $scope.showPopup = function () {
                console.log($scope.ngModel);
                $scope.ngModel = !$scope.ngModel;
            }
        }
    }
})

Demo on jsFiddle

Upvotes: 1

Yann
Yann

Reputation: 2231

In order to make sure each of your directive as a different scope, you could add a scope : true to the object returned by your directive function.

You should definitely check out the documentation ("Writing directives (long version)"), it explains the power of the scope attribute, how to isolate the scope, bind arguments, etc...

This stackoverflow question provides an even better explanation.

Upvotes: 1

Related Questions