사용자가 해당 드롭 다운 외부의 아무 곳이나 클릭하면 로그인 메뉴 드롭 다운을 닫고 싶습니다. Angular2와 Angular2 "접근법"으로 수행하고 싶습니다 ...
솔루션을 구현했지만 실제로는 자신감이 없습니다. 나는 같은 결과를 얻는 가장 쉬운 방법이 있어야한다고 생각하므로 아이디어가 있다면 ... : 토론합시다!
내 구현은 다음과 같습니다.
드롭 다운 구성 요소 :
이것은 내 드롭 다운의 구성 요소입니다.
- 이 컴포넌트가 표시되도록 설정할 때마다 (예 : 사용자가 버튼을 클릭하여 표시 할 때) SubjectsService 내에 저장된 "global"rxjs subject userMenu를 구독합니다 .
- 그리고 숨길 때마다이 주제를 구독 취소합니다.
- 이 구성 요소의 템플릿 내 어디에서나 클릭 할 때마다 onClick () 메서드가 트리거됩니다.이 메서드는 이벤트 버블 링을 맨 위 (및 응용 프로그램 구성 요소)로 중지합니다.
여기 코드가 있습니다
export class UserMenuComponent {
_isVisible: boolean = false;
_subscriptions: Subscription<any> = null;
constructor(public subjects: SubjectsService) {
}
onClick(event) {
event.stopPropagation();
}
set isVisible(v) {
if( v ){
setTimeout( () => {
this._subscriptions = this.subjects.userMenu.subscribe((e) => {
this.isVisible = false;
})
}, 0);
} else {
this._subscriptions.unsubscribe();
}
this._isVisible = v;
}
get isVisible() {
return this._isVisible;
}
}
응용 프로그램 구성 요소 :
반면에 응용 프로그램 구성 요소 (드롭 다운 구성 요소의 부모)가 있습니다.
- 이 구성 요소는 모든 클릭 이벤트를 포착하고 동일한 rxjs 주제 ( userMenu )에서 생성합니다.
코드는 다음과 같습니다.
export class AppComponent {
constructor( public subjects: SubjectsService) {
document.addEventListener('click', () => this.onClick());
}
onClick( ) {
this.subjects.userMenu.next({});
}
}
나를 귀찮게하는 것 :
- 나는 그 구성 요소들 사이의 커넥터 역할을하는 글로벌 주제를 가지고 있다는 생각에 정말로 편안하지 않습니다.
- 에서는 setTimeout : 여기에 사용자가 버튼을 클릭 드롭 다운을 표시하는 경우, 그렇지 않으면 일이 무엇 때문이 필요합니다 :
- 드롭 다운 구성 요소의 일부가 아닌 단추를 클릭하면 드롭 다운이 표시됩니다.
- 드롭 다운이 표시되고 즉시 userMenu 주제를 구독합니다 .
- 클릭 이벤트가 앱 구성 요소에 버블 링되어 붙잡음
- 응용 프로그램 구성 요소가 userMenu 주제 에서 이벤트를 생성합니다.
- 드롭 다운 컴포넌트는 userMenu 에서이 조치를 포착 하고 드롭 다운을 숨 깁니다.
- 마지막에 드롭 다운이 표시되지 않습니다.
이 설정 시간 초과는 현재 JavaScript 코드 턴의 끝까지 구독을 지연시켜 문제를 해결하지만 매우 우아하게 생각합니다.
더 깨끗하고, 더 똑똑하고, 더 빠르거나 강한 솔루션을 알고 있다면 알려주세요 :)!