형제자매 지시사항과 의사소통
목표: 두 형제 요소(각각의 지시사항) 간의 의사소통을 통해 지시사항을 사용하여 행동을 만듭니다.
예제에서 사용할 동작:기사 내용은 기본적으로 숨겨집니다.제목을 클릭하면 관련 기사 내용이 표시되기를 원합니다.
문제점:관련 기사 요소는 하나의 상위 요소나 지시문에 중첩되지 않고 서로 연결해야 합니다.
<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>
기사 지시문 안에 내용을 넣는 것이 더 쉽겠지만, 이 문제는 이런 상황을 어떻게 해결할 것인가를 알아보는 것입니다.
내용 지시가 어떻게든 관련 기사 지시에 전달될 수 있습니까?
이 코드는 지금처럼 유용하지는 않지만 출발점입니다.어떻게 해야 이걸 해낼 수 있을까요?
.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
옵션을 사용하면 형제 지시가 필요한 것으로 알고 있습니다.다음만 가능:
- 요소에 요구, 사용
require: "directiveName"
- 각도를 지정하여 DOM 트리를 검색합니다.
require: "^directiveName"
- 아니면
require: "^?directiveName"
부모 컨트롤러가 꼭 필요하지 않은 경우 - 아니면
require: "^\?directiveName"
반드시 상위 DOM 래퍼가 필요하지 않은 경우
형제간 통신을 원할 경우, 형제간 통신을 위한 API 역할을 하는 지시 컨트롤러와 함께 일부 부모 DOM 요소에 이들을 수용해야 합니다.이를 구현하는 방법은 주로 당면한 상황에 따라 달라집니다.
Angular JS(오 레일리)의 좋은 예를 소개합니다.
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.
아니면, 당신은 당신이.service
단지 지시적인 의사소통을 위해, 특별한 한가지 장점.service
대require
지시사항이 HTML 구조에서 그들의 위치에 의존하지 않는다는 것입니다.
위의 솔루션은 훌륭하며, 지시사항 간에 의사소통이 가능하도록 상위 범위를 사용하는 것을 확실히 고려해야 합니다.그러나 구현이 매우 간단하다면 부모를 사용하지 않고 두 형제 스코프 간에 통신할 수 있는 Angular에 내장된 쉬운 방법이 있습니다.$emit
,$broadcast
,그리고.$on
.
예를 들어, 복잡한 서비스를 입력하는 탐색바 검색창이 있는 꽤 간단한 앱 계층 구조를 가지고 있으며, 페이지의 다양한 다른 지시사항으로 결과를 브로드캐스트하려면 해당 서비스가 필요합니다.이를 위한 한 가지 방법은 다음과 같습니다.
수색대에서
$rootScope.$emit('mySearchResultsDone', {
someData: 'myData'
});
다른 어떤 지시/통제자들에게서
$rootScope.$on('mySearchResultsDone', function(event, data) {
vm.results = data;
});
그 코드가 얼마나 단순한지에 대해서는 어떤 아름다움이 있습니다.그러나 방송 및 청취 장소가 여러 곳인 경우 방송/온/방송 논리가 매우 빨리 심해질 수 있음을 명심해야 합니다.빠른 구글 검색은 안티 패턴이 아닌 때에 대한 많은 의견을 보여줄 수 있습니다.
다음 게시물에서 방송/방송/온에 대한 몇 가지 좋은 통찰력:
http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
http://nathanleclaire.com/blog/2014/04/19/5-angularjs-antipatterns-and-pitfalls/
기사 목록과 그 내용이 있다면 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>
따라서 컨트롤러에서 아티클 모델을 정의해야 합니다.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>
그리고 당신의 지시에 따라
사용하다
link: function(scope, element,attrs) {
element.bind('click', function(){
$('#'+attrs.content).show();
}
}
그리고 최종적인 방법은 그들이 사용하는 것입니다.$rootScope.$broadcast
그리고.scope.$on
컨트롤러와 통신하는 방법.그러나 이 방법에서는 메시지가 어디에서 왔는지, 메시지를 처리해야 할 수신자가 누구인지 추적해야 합니다.
저도 똑같은 문제가 있어서 해결할 수 있었습니다.
다른 형제 지시를 숨기기 위해 하나의 지시를 얻기 위해 API 역할을 하는 부모 지시를 사용했습니다.한 하위 지침은 해당 요소에 대한 참조를 전달하여 부모에게 표시/숨기지 않아야 한다고 말하고, 다른 하위 지침은 부모 토글 함수를 호출합니다.
app.directive("parentapi", function() {
return {
restrict: "E",
scope: {},
controller: function($scope) {
$scope.elements = [];
var on = true;
this.toggleElements = function() {
if(on) {
on = false;
_.each($scope.elements, function(el) {
$(el).hide();
});
} else {
on = true;
_.each($scope.elements, function(el) {
$(el).show();
});
}
}
this.addElement = function(el) {
$scope.elements.push(el);
}
}
}
});
app.directive("kidtoggle", function() {
return {
restrict: "A",
require: "^parentapi",
link: function(scope, element, attrs, ctrl) {
element.bind('click', function() {
ctrl.toggleElements();
});
}
}
});
app.directive("kidhide", function() {
return {
restrict: "A",
require: "^parentapi",
link: function(scope, element, attrs, ctrl) {
ctrl.addElement(element);
}
}
});
제가 작성하던 select all/select item direction에 대해서도 같은 문제가 있었습니다.제 문제는 select all 확인란이 테이블 헤더 행에 있고 select 항목이 테이블 본문에 있다는 것입니다.저는 펍/서브 알림 서비스를 시행하여 안내자들이 서로 대화할 수 있도록 하였습니다.이런 식으로 나의 지시는 내 htlm이 어떻게 구성되었는지에 대해 신경쓰지 않았습니다.꼭 필요한 부동산을 이용하고 싶었지만, 서비스를 이용하는 것도 효과가 있었습니다.
언급URL : https://stackoverflow.com/questions/18245388/communicating-with-sibling-directives
'programing' 카테고리의 다른 글
반응 네이티브 고정 바닥글 (0) | 2023.10.06 |
---|---|
mariadb에서 타임스탬프를 사용하여 사용자 지정 기본 키를 생성하는 방법 (0) | 2023.10.06 |
InnoDB 테이블을 My ISAM 테이블과 결합하는 중 (0) | 2023.10.06 |
여러 플롯을 하나의 PDF 파일에 저장 (0) | 2023.10.06 |
오버플로된 Div 내의 요소로 스크롤하려면 어떻게 해야 합니까? (0) | 2023.10.06 |