2

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>'      
    }
  });
Eduard Gamonal
  • 8,023
  • 5
  • 41
  • 46
otissv
  • 815
  • 1
  • 10
  • 17

3 Answers3

1

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.

Community
  • 1
  • 1
Yann
  • 2,211
  • 1
  • 15
  • 14
  • scope:true doesn't work as it isolates $scope.popup from the pop directive. The documentation is down at the moment so will read your link. – otissv Jul 31 '13 at 16:24
1

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

zs2020
  • 53,766
  • 29
  • 154
  • 219
  • yep this works too. The only thing is I don't like using ng-init as it's logic in my view. – otissv Aug 01 '13 at 12:30
  • Ok, you can move that initialization logic to the controller. I just wanted to demo the code and simplify a bit. – zs2020 Aug 01 '13 at 13:33
0

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;
    }
  }
otissv
  • 815
  • 1
  • 10
  • 17