Cod*_*er1 22 angularjs angularjs-directive
目标:使用指令在两个兄弟元素之间进行通信来创建行为(每个元素都有自己的指令).
在示例中使用的行为:默认情况下隐藏文章内容.单击标题时,我希望显示相关的文章内容.
catch:相关的article元素需要彼此关联,而不是嵌套在单个父元素或指令中.
<div article="article1">this is my header</div>
<div id="article1" article-content>this is content for the header above</div>
<div article="article2">this is my header</div>
<div id="article2" article-content>this is content for the header above</div>
Run Code Online (Sandbox Code Playgroud)
我知道将内容放在article指令中更容易,但是这个问题是要找出如何解决这样的情况.
内容指令能否以某种方式将自身传递给相关的文章指令?
这段代码现在不是很有用,但它是一个起点.我怎么做到这一点?
.directive('article', function(){
return {
restrict: "A",
controller: function($scope) {
$scope.contentElement = null;
this.setContentElement = function(element) {
$scope.contentElement = element;
}
},
link: function(scope, element) {
element.bind('click', function(){
// Show article-content directives that belong
// to this instance (article1) of the directive
}
}
}
}
.directive('articleContent', function(){
return {
require: "article",
link: function(scope, element, attrs, articleCtrl) {
// Maybe reference the article i belong to and assign element to it?
// I can't though because these are siblings.
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ian*_*rty 32
没有任何指令require选项允许您要求兄弟指令(据我所知).你只能:
require: "directiveName"require: "^directiveName"require: "^?directiveName"如果您不一定需要父控制器require: "^\?directiveName"如果您不一定需要父DOM包装器如果你想兄弟姐妹进行兄弟姐妹的沟通,你必须将它们放在一些父DOM元素中,并使用指令控制器充当他们沟通的API.如何实现这在很大程度上取决于手头的背景.
以下是Angular JS(O Reilly)的一个很好的例子
app.directive('accordion', function() {
return {
restrict: 'EA',
replace: true,
transclude: true,
template: '<div class="accordion" 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);
}
}
}
});
app.directive('expander', function() {
return {
restrict: 'EA',
replace: true,
transclude: true,
require: '^?accordion',
scope: { title:'@' },
template: '<div class="expander">\n <div class="title" ng-click="toggle()">{{ title }}</div>\n <div class="body" ng-show="showMe" \n ng-animate="{ show: \'animated flipInX\' }"\n ng-transclude></div>\n</div>',
link: function(scope, element, attrs, accordionController) {
scope.showMe = false;
accordionController.addExpander(scope);
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
accordionController.gotOpened(scope);
}
}
}
})
Run Code Online (Sandbox Code Playgroud)
用法(玉石模板):
accordion
expander(title="An expander") Woohoo! You can see mme
expander(title="Hidden") I was hidden!
expander(title="Stop Work") Seriously, I am going to stop working now.
Run Code Online (Sandbox Code Playgroud)
Iva*_* V. 10
或者你可以创建一个servicejust for directive通信,special servicevs的一个优点require是你的指令不依赖于它们在html结构中的位置.
如果有文章及其内容的列表,我们可以使用 ng-repeat 来完成,无需任何指令
<div ng-repeat="article in articles">
<div article="article1" ng-click='showContent=true'>{{article.header}}</div>
<div id="article1" article-content ng-show='showContent'>{{article.content}}</div>
</div>
Run Code Online (Sandbox Code Playgroud)
所以你需要在控制器中定义文章模型。我们正在利用 ng-repeat 创建的本地范围。
更新:根据您的反馈,您需要将它们链接在一起。您可以尝试
<div article="article1" content='article1'>this is my header</div>
<div id="article1" article-content>this is content for the header above</div>
Run Code Online (Sandbox Code Playgroud)
并在您的指令中
使用
link: function(scope, element,attrs) {
element.bind('click', function(){
$('#'+attrs.content).show();
}
}
Run Code Online (Sandbox Code Playgroud)
最后的方法可能是使用$rootScope.$broadcast和scope.$on方法在控制器之间进行通信。但在这种方法中,您需要跟踪消息的来源以及谁是需要处理该消息的预期收件人。