Multiple AngularJS directives with different scope

2019-07-17 03:33发布

问题:

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>'      
    }
  });

回答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



回答2:

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.



回答3:

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;
    }
  }