尝试访问范围时 angular-bootstrap 指令中的问题

Issue in angular-bootstrap directive while trying to access scope

我已将 https://github.com/angular-ui/bootstrap 用于手风琴,但使用此指令时我遇到了范围问题。如果在手风琴内部声明了 ngController,它只允许使用范围。

请访问以下两个 Plunker 链接,您就会明白我想说的是什么:

示例 1http://plnkr.co/edit/Fb4UauWWmHOnTyjMPFBo

index.html

<!doctype html>
<html ng-app="plunker">
<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-animate.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.4.js"></script>
  <script src="script.js"></script>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>  
  <div ng-controller="AccordionDemoCtrl">
    <accordion>
      <accordion-group is-open="status.open">
        <accordion-heading>
          Accordian - Click me <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
        </accordion-heading>
        <div>
          <input type="checkbox" ng-model="select" ng-click="checkAll()" /> Check me
        </div>
      </accordion-group>
    </accordion>
  </div>
</body>
</html>

script.js

var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('AccordionDemoCtrl', function($scope) {
  $scope.checkAll = function() {
    alert($scope.select);
  };
});

示例 2http://plnkr.co/edit/ljEMUnTqPBqUyub5eEB7

index.html

<!doctype html>
<html ng-app="plunker">
<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-animate.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.4.js"></script>
  <script src="script.js"></script>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <accordion>
    <accordion-group is-open="status.open">
      <accordion-heading>
        Accordian - Click me <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
      </accordion-heading>
      <div ng-controller="AccordionDemoCtrl">
        <input type="checkbox" ng-model="select" ng-click="checkAll()" /> Check me
      </div>
    </accordion-group>
  </accordion>
</body>
</html>

script.js

var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('AccordionDemoCtrl', function($scope) {
  $scope.checkAll = function() {
    alert($scope.select);
  };
});

发生这种情况是因为 directiveaccordionGroup”在 AngularBootstrap 中的 scopeisolatedcontroller$scope "AccordionDemoCtrl" 是在 "directive".

中使用 require 继承的

因此,对于 Example1,当您尝试访问 accordian group directiveAccordionDemoCtrl$scope 绑定时,它很容易访问。但是由于 selectlocal scope of accordian group directive 中,因此在控制器中无法访问。

因此,对于 Example2,当您尝试访问 accordian group directiveAccordionDemoCtrl$scope 绑定时,它很容易访问,因为controller在本地scopeaccordian group

请参考directive to directive Comm.

这是来自 Angular Bootstrap Accordian 库的代码

.directive('accordion', function () {
  return {
    restrict:'EA',
    controller:'AccordionController',
    transclude: true,
    replace: false,
    templateUrl: 'template/accordion/accordion.html'
  };
})

// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
.directive('accordionGroup', function() {
  return {
    require:'^accordion',         // We need this directive to be inside an accordion
    restrict:'EA',
    transclude:true,              // It transcludes the contents of the directive into the template
    replace: true,                // The element containing the directive will be replaced with the template
    templateUrl:'template/accordion/accordion-group.html',
    scope: {
      heading: '@',               // Interpolate the heading attribute onto this scope
      isOpen: '=?',
      isDisabled: '=?'
    },
    controller: function() {
      this.setHeading = function(element) {
        this.heading = element;
      };
    },
    link: function(scope, element, attrs, accordionCtrl) {
      accordionCtrl.addGroup(scope);

      scope.$watch('isOpen', function(value) {
        if ( value ) {
          accordionCtrl.closeOthers(scope);
        }
      });

      scope.toggleOpen = function() {
        if ( !scope.isDisabled ) {
          scope.isOpen = !scope.isOpen;
        }
      };
    }
  };
})

// Use accordion-heading below an accordion-group to provide a heading containing HTML
// <accordion-group>
//   <accordion-heading>Heading containing HTML - <img src="..."></accordion-heading>
// </accordion-group>
.directive('accordionHeading', function() {
  return {
    restrict: 'EA',
    transclude: true,   // Grab the contents to be used as the heading
    template: '',       // In effect remove this element!
    replace: true,
    require: '^accordionGroup',
    link: function(scope, element, attr, accordionGroupCtrl, transclude) {
      // Pass the heading to the accordion-group controller
      // so that it can be transcluded into the right place in the template
      // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
      accordionGroupCtrl.setHeading(transclude(scope, function() {}));
    }
  };
})

我找到了解决方案:

我们可以从函数本身传递值,而不需要使用 $scope 访问值。

演示:http://plnkr.co/edit/fZZrDN4e8kbvimR2Wzya

index.html

<!doctype html>
<html ng-app="plunker">

<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-animate.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.4.js"></script>
  <script src="script.js"></script>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>

  <div ng-controller="AccordionDemoCtrl">
    <accordion>
      <accordion-group is-open="status.open">
        <accordion-heading>
          Accordian - Click me <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
        </accordion-heading>
        <div>
          <input type="checkbox" ng-model="select" ng-click="checkAll(select)" /> Check me
        </div>
      </accordion-group>
    </accordion>
  </div>
</body>

</html>

script.js:

var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('AccordionDemoCtrl', function($scope) {
  $scope.checkAll = function (select) {
    alert(select);
  };
});