이벤트 리스너 동적 추가
이제 막 Angular 2를 만지작거리기 시작했는데, 이벤트 청취자를 요소에서 동적으로 추가하고 제거할 수 있는 가장 좋은 방법을 알려줄 수 있는지 궁금합니다.
컴포넌트를 설정했습니다.템플릿의 특정 요소를 클릭하면 다음 항목에 대해 청취자를 추가합니다.mousemove
같은 템플릿의 다른 요소로 이동합니다.그런 다음 세 번째 요소를 클릭하면 이 수신기를 제거합니다.
플레인 Javascript를 사용하여 요소를 잡고 표준을 호출하는 것만으로 이 작업을 수행할 수 있습니다.addEventListener()
'Angular2'가 더 있을까?내가 조사해야 할 0" 방법.
렌더러가 Angular 4.0.0-rc.1에서 더 이상 사용되지 않습니다. 아래 업데이트를 읽어 보십시오.
angular2의 방법은listen
또는listenGlobal
렌더러에서
예를 들어 클릭 이벤트를 컴포넌트에 추가하려면 Renderer와 ElementRef를 사용해야 합니다(ViewChild를 사용할 수 있는 옵션 또는nativeElement
)
constructor(elementRef: ElementRef, renderer: Renderer) {
// Listen to click events in the component
renderer.listen(elementRef.nativeElement, 'click', (event) => {
// Do something with 'event'
})
);
사용할 수 있습니다.listenGlobal
에 액세스 할 수 있습니다.document
,body
,기타.
renderer.listenGlobal('document', 'click', (event) => {
// Do something with 'event'
});
beta.2 이후 두 가지 모두listen
그리고.listenGlobal
수신기를 제거하는 함수를 반환합니다(beta.2에 대한 changelog의 breaking changes 섹션 참조).이는 대규모 애플리케이션에서 메모리 누수를 방지하기 위한 것입니다(#6686 참조).
그래서 동적으로 추가한 청취자를 제거하려면listen
또는listenGlobal
반환된 함수를 유지할 변수에 도달한 후 실행합니다.
// listenFunc will hold the function returned by "renderer.listen"
listenFunc: Function;
// globalListenFunc will hold the function returned by "renderer.listenGlobal"
globalListenFunc: Function;
constructor(elementRef: ElementRef, renderer: Renderer) {
// We cache the function "listen" returns
this.listenFunc = renderer.listen(elementRef.nativeElement, 'click', (event) => {
// Do something with 'event'
});
// We cache the function "listenGlobal" returns
this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
// Do something with 'event'
});
}
ngOnDestroy() {
// We execute both functions to remove the respectives listeners
// Removes "listen" listener
this.listenFunc();
// Removs "listenGlobal" listener
this.globalListenFunc();
}
여기 작업 예제가 있는 plnkr가 있습니다.이 예에는, 다음의 사용법이 포함되어 있습니다.listen
그리고.listenGlobal
.
Angular 4.0.0-rc.1+에서의 RendererV2 사용
2017년 2월 25일:
Renderer
는 더 이상 사용되지 않습니다(아래 행 참조).커밋을 참조해 주세요.2017년 10월 3일 :
RendererV2
로 이름이 변경되었습니다.Renderer2
. 변경 사항을 확인하십시오.
RendererV2
더 이상 없다listenGlobal
글로벌 이벤트(예: 본문, 창)에 대해 기능을 수행합니다.이밖에 없어요.listen
두 가지 기능을 모두 실현하는 기능.
참고로 DOM 렌더러 구현의 소스 코드가 변경될 수 있으므로 복사하여 붙여넣습니다(네, 각도입니다).
listen(target: 'window'|'document'|'body'|any, event: string, callback: (event: any) => boolean):
() => void {
if (typeof target === 'string') {
return <() => void>this.eventManager.addGlobalEventListener(
target, event, decoratePreventDefault(callback));
}
return <() => void>this.eventManager.addEventListener(
target, event, decoratePreventDefault(callback)) as() => void;
}
보시는 바와 같이 문자열(문서, 본문 또는 창)이 전달되고 있는지 확인합니다.이 경우 내부가 사용됩니다.addGlobalEventListener
기능.어떤 경우에도 요소(네이티브 요소)를 전달하면 단순 요소가 사용됩니다.addEventListener
사람을 은 '듣는 사람'과 Renderer
2.listen
함수를 반환하고 해당 함수를 호출합니다.
예
// Add listeners
let global = this.renderer.listen('document', 'click', (evt) => {
console.log('Clicking the document', evt);
})
let simple = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {
console.log('Clicking the button', evt);
});
// Remove listeners
global();
simple();
Renderer V2를 사용한 Angular 4.0.0-rc.1의 plnkr
Renderer2를 사용한 Angular 4.0.0-rc.3의 plnkr
StackBlitz의 예시와 @tahiche로부터의 코멘트를 추가합니다.
반환값은 이벤트청취자를 추가한 후 삭제하는 함수입니다.이벤트 청취자가 더 이상 필요하지 않을 때는 이를 제거하는 것이 좋은 관행으로 간주됩니다. 이 할 수 .ngOnDestroy
★★★★★★ 。
처음에는 혼란스러워 보일 수 있다는 것을 인정하지만, 실제로는 매우 유용한 기능입니다.아니면 어떻게 뒷처리를 할 수 있겠어요?
export class MyComponent implements OnInit, OnDestroy {
public removeEventListener: () => void;
constructor(
private renderer: Renderer2,
private elementRef: ElementRef
) {
}
public ngOnInit() {
this.removeEventListener = this.renderer.listen(this.elementRef.nativeElement, 'click', (event) => {
if (event.target instanceof HTMLAnchorElement) {
// Prevent opening anchors the default way
event.preventDefault();
// Your custom anchor click event handler
this.handleAnchorClick(event);
}
});
}
public ngOnDestroy() {
this.removeEventListener();
}
}
StackBlitz는 앵커 요소를 클릭할 때 어떻게 동작하는지 보여 주는 기능을 제공합니다.
.
<img src="x" onerror="alert(1)"></div>
세정제가 제 역할을 하고 있다는 걸 보여주기 위해서요
이 바이올린을 켜면 같은 시체가 붙어 있는 걸 볼 수 있어요innerHTML
소거하지 않고 문제를 증명해 보일 것입니다.
나는 이것이 매우 혼란스럽다고 생각한다.@EricMartinez가 Renderer2 listen()을 지적한 것처럼 리스너를 삭제하는 함수를 반환합니다.
ƒ () { return element.removeEventListener(eventName, /** @type {?} */ (handler), false); }
청취자를 추가하는 경우
this.listenToClick = this.renderer.listen('document', 'click', (evt) => {
alert('Clicking the document');
})
듣는 사람을 제거하는 기능이 아니라 내가 의도한 것을 실행하는 기능을 기대합니다.
// I´d expect an alert('Clicking the document');
this.listenToClick();
// what you actually get is removing the listener, so nothing...
주어진 시나리오에서는 실제로 다음과 같은 이름을 붙이는 것이 더 합리적입니다.
// Add listeners
let unlistenGlobal = this.renderer.listen('document', 'click', (evt) => {
console.log('Clicking the document', evt);
})
let removeSimple = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {
console.log('Clicking the button', evt);
});
여기에는 분명 그럴 만한 이유가 있겠지만, 내 생각에 그것은 매우 오해의 소지가 있고 직관적이지 않다.
회피책은 다음과 같습니다.
각진 6자 모양 성분을 했습니다.commonlib-header
외부 응용 프로그램에서는 이렇게 사용됩니다.
해 주세요.serviceReference
있는 클래스)입니다.constructor(public serviceReference: MyService)
쓰입니다.commonlib-header
를 수용하고 .stringFunctionName
★★★★
<commonlib-header
[logo]="{ src: 'assets/img/logo.svg', alt: 'Logo', href: '#' }"
[buttons]="[{ index: 0, innerHtml: 'Button', class: 'btn btn-primary', onClick: [serviceReference, 'stringFunctionName', ['arg1','arg2','arg3']] }]">
</common-header>
라이브러리 구성요소는 다음과 같이 프로그래밍됩니다.다이내믹 이벤트가 에 추가됩니다.onClick(fn: any)
★★★★
export class HeaderComponent implements OnInit {
_buttons: Array<NavItem> = []
@Input()
set buttons(buttons: Array<any>) {
buttons.forEach(navItem => {
let _navItem = new NavItem(navItem.href, navItem.innerHtml)
_navItem.class = navItem.class
_navItem.onClick = navItem.onClick // this is the array from the component @Input properties above
this._buttons[navItem.index] = _navItem
})
}
constructor() {}
ngOnInit() {}
onClick(fn: any){
let ref = fn[0]
let fnName = fn[1]
let args = fn[2]
ref[fnName].apply(ref, args)
}
가능한 " " "header.component.html
:
<div class="topbar-right">
<button *ngFor="let btn of _buttons"
class="{{ btn.class }}"
(click)="onClick(btn.onClick)"
[innerHTML]="btn.innerHtml | keepHtml"></button>
</div>
언급URL : https://stackoverflow.com/questions/35080387/dynamically-add-event-listener
'programing' 카테고리의 다른 글
프로그래밍 방식으로 포커스 입력에 반응하는 방법 (0) | 2023.03.04 |
---|---|
React 앱을 서버의 서브 디렉토리에 번들하려면 어떻게 해야 합니까? (0) | 2023.03.04 |
로컬 파일로 요청을 가져올 수 없습니다. (0) | 2023.02.27 |
woocommerce: 제품 속성에 값 추가 (0) | 2023.02.27 |
각도 - 사용자 지정 메서드를 사용하는 $resource 하위 개체 확장 (0) | 2023.02.27 |