Directive间的通信
源自大漠的《AngularJS》5个实例详解Directive(指令)机制
这个例子主要的难点在于如何在子Expander里面访问外层Accordion的scope中的数据
注释解读一下
JS代码:
var expModule=angular.module('expanderModule',[])
expModule.directive('accordion', function() {
return {
restrict : 'EA',
replace : true,
//这里没有定义scope,将使用元素上的scope,就是下面ng-controller指定的SomeController的scope
transclude : true,
template : '<div ng-transclude></div>',
controller : function() {
var expanders = [];
this.gotOpened = function(selectedExpander) {
angular.forEach(expanders, function(expander) {
if (selectedExpander != expander) {
expander.showMe = false;
}
});
}
this.addExpander = function(expander) {
expanders.push(expander);
}
}
}
});
expModule.directive('expander', function() {
return {
restrict : 'EA',
replace : true,
transclude : true,
require : '^?accordion', //依赖
scope : {
title : '=expanderTitle'
},
template : '<div>'
+ '<div class="title" ng-click="toggle()">{{title}}</div>'
+ '<div class="body" ng-show="showMe" ng-transclude></div>'
+ '</div>',
link : function(scope, element, attrs, accordionController) {
//注意link的第四个参数
scope.showMe = false;
accordionController.addExpander(scope);//调用外层指令的方法
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
accordionController.gotOpened(scope);//调用外层指令的方法
}
}
}
});
expModule.controller("SomeController",function($scope) {
$scope.expanders = [{
title : 'Click me to expand',
text : 'Hi there folks, I am the content that was hidden but is now shown.'
}, {
title : 'Click this',
text : 'I am even better text than you have seen previously'
}, {
title : 'Test',
text : 'test'
}];
});
HTML代码:
<html ng-app="expanderModule">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../angular-1.0.3/angular.min.js"></script>
<link rel="stylesheet" type="text/css" href="Accordion.css"/>
</head>
<body ng-controller='SomeController' >
<accordion>
<expander class='expander' ng-repeat='expander in expanders' expander-title='expander.title'>
{{expander.text}}
</expander>
</accordion>
</body>
<script src="Accordion.js"></script>
</html>
CSS代码:
.expander {
border: 1px solid black;
250px;
}
.expander>.title {
background-color: black;
color: white;
padding: .1em .3em;
cursor: pointer;
}
.expander>.body {
padding: .1em .3em;
}
运行效果:
require option
看看官网的原文怎么说
The myPane directive has a require option with value ^^myTabs. When a directive uses this option, $compile will throw an error unless the specified controller is found.
.The ^^ prefix means that this directive searches for the controller on its parents.
.The ^ prefix would make the directive look for the controller on its own element or its parents;
.without any prefix, the directive would look on its own element only.
.The ? prefix, if not found then pass null to the link as the fourth parameter
link函数的参数
Creating a Directive that Manipulates the DOM
link
takes a function with the following signature, function link(scope, element, attrs, controller, transcludeFn) { ... }
, where:
. scope is an Angular scope object.
. element is the jqLite-wrapped element that this directive matches.
. attrs is a hash object with key-value pairs of normalized attribute names and their corresponding attribute values.
. controller is the directive's required controller instance(s) or its own controller (if any). The exact value depends on the directive's require property.
. transcludeFn is a transclude linking function pre-bound to the correct transclusion scope.