尝试访问范围时 angular-bootstrap 指令中的问题
Issue in angular-bootstrap directive while trying to access scope
我已将 https://github.com/angular-ui/bootstrap 用于手风琴,但使用此指令时我遇到了范围问题。如果在手风琴内部声明了 ngController,它只允许使用范围。
请访问以下两个 Plunker 链接,您就会明白我想说的是什么:
示例 1:http://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);
};
});
示例 2:http://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);
};
});
发生这种情况是因为 directive
“accordionGroup
”在 AngularBootstrap 中的 scope
是isolated
和 controller
的 $scope
"AccordionDemoCtrl
" 是在 "directive
".
中使用 require
继承的
因此,对于 Example1,当您尝试访问 accordian group
directive
中 AccordionDemoCtrl
的 $scope
绑定时,它很容易访问。但是由于 select
在 local
scope
of accordian group
directive
中,因此在控制器中无法访问。
因此,对于 Example2,当您尝试访问 accordian group directive
中 AccordionDemoCtrl
的 $scope
绑定时,它很容易访问,因为controller在本地scope
为accordian 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);
};
});
我已将 https://github.com/angular-ui/bootstrap 用于手风琴,但使用此指令时我遇到了范围问题。如果在手风琴内部声明了 ngController,它只允许使用范围。
请访问以下两个 Plunker 链接,您就会明白我想说的是什么:
示例 1:http://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);
};
});
示例 2:http://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);
};
});
发生这种情况是因为 directive
“accordionGroup
”在 AngularBootstrap 中的 scope
是isolated
和 controller
的 $scope
"AccordionDemoCtrl
" 是在 "directive
".
require
继承的
因此,对于 Example1,当您尝试访问 accordian group
directive
中 AccordionDemoCtrl
的 $scope
绑定时,它很容易访问。但是由于 select
在 local
scope
of accordian group
directive
中,因此在控制器中无法访问。
因此,对于 Example2,当您尝试访问 accordian group directive
中 AccordionDemoCtrl
的 $scope
绑定时,它很容易访问,因为controller在本地scope
为accordian 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);
};
});