与兄弟指令通信 [英] Communicating with sibling directives
问题描述
目标:使用指令创建行为,并在 2 个兄弟元素(每个元素都有自己的指令)之间进行通信.
Goal: Create behaviors using directives with communication between 2 sibling elements (each their own directive).
示例中使用的行为:文章内容默认隐藏.单击标题时,我希望显示相关文章内容.
A behavior to use in example: The article content is hidden by default. When the title is clicked, I want the related article content to display.
问题:相关的文章元素需要相互关联,而不是嵌套在单个父元素或指令中.
The catch: The related article elements need to associate to each other without being nested in a single parent element or directive.
<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>
我知道将内容放在文章指令中会更容易,但是这个问题是要找出如何解决这样的情况.
I know it would be easier to place the content inside the article directive, however this question is to find out how to solve a situation like this.
内容指令能否以某种方式将自身传递给相关的文章指令?
Can the content directive pass itself to the related article directive somehow?
这段代码不像现在那么有用,但它是一个起点.我将如何做到这一点?
This code isn't very useful as it is now, but it's a starting point. How would I accomplish this?
.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.
}
}
}
推荐答案
没有一个指令 require
允许你要求兄弟指令(据我所知).您只能:
None of the directive require
options will allow you to require sibling directives (as far as I know). You can only:
- 在元素上需要,使用
require: "directiveName"
- 告诉 angular 使用
require: "^directiveName"
搜索 DOM 树 - 或
require: "^?directiveName"
如果您不一定需要父控制器 - 或
require: "^\?directiveName"
如果您不一定需要父 DOM 包装器
- require on the element, using
require: "directiveName"
- tell angular to search up the DOM tree using
require: "^directiveName"
- or
require: "^?directiveName"
if you don't necessarily need the parent controller - or
require: "^\?directiveName"
if you don't necessarily need the parent DOM wrapper
如果你想要兄弟之间的通信,你必须将它们放在一些父 DOM 元素中,并使用一个指令控制器作为它们通信的 API.如何实现在很大程度上取决于手头的上下文.
If you want sibling to sibling communication, you'll have to house them in some parent DOM element with a directive controller acting as an API for their communication. How this is implemented is largely dependent on the context at hand.
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);
}
}
}
})
用法(玉石模板):
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.
这篇关于与兄弟指令通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!