由于没有模板,在指令中监听子元素事件的最佳方法是什么? HostListener
可以吗?如果没有,还有其他办法吗?
还有这个类似的问题:How to listen for child event from parent directive in Angular2,但建议的方法并不能解决我的问题,因为我的指令和子元素不在同一个模板中(指令在主机上)
干杯!
编辑#1
这就是我目前正在做的事情(必须有更好的方法):
首先将ElementRef
注入我的指令:
constructor(private elView: ElementRef) {}
然后用jQuery(或普通JS)绑定:
$(this.elView.nativeElement)
.on('drag', '#childId', this.slide.bind(this))
答案 0 :(得分:7)
如果您要收听的事件是冒泡的本机DOM事件,那么您可以使用@HostListener()
@HostListener('click', ['$event'])
handleClick(event) {
// handle event
}
如果它们是子组件的输出,您可以查询它们并订阅它们的输出
@ContentChildren(ChildComponent) children:QueryList<ChildComponent>;
ngAfterContentInit() {
this.children.toArray().forEach((item) => {
item.someOutput.subscribe(...);
});
}
或者您可以使用您在问题中链接的答案中使用的方法。
答案 1 :(得分:1)
您可以考虑让您的组件通过服务类相互通信。
// service class
class Service {
private someEventSource = new Subject();
public someEvent = this.someEventSource.asObservable();
public invokeAnEvent (data: string) {
this.someEventSource.next(data);
}
}
// parentComponent class
Service.someEvent.subscribe(data => {
console.log(data);
});
// childComponent class
Service.invokeAnEvent('some data to pass');
来自Angular文档:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
答案 2 :(得分:0)
我对这个问题的解决方案是在根组件ngAfterContentChecked
中添加并选择我所有相关的元素并添加事件。例如:
ngAfterContentChecked() {
//console.log('MASTER ngAfterContentChecked')
let rgx = /^[0-9,\.]+$/;
let preventNonNumber = e => {
//let v = (e.target as HTMLInputElement).value
if (
// Allow: Delete, Backspace, Tab, Escape, Enter
[46, 8, 9, 27, 13].indexOf(e.keyCode) !== -1 ||
(e.keyCode === 65 && e.ctrlKey === true) || // Allow: Ctrl+A
(e.keyCode === 67 && e.ctrlKey === true) || // Allow: Ctrl+C
(e.keyCode === 86 && e.ctrlKey === true) || // Allow: Ctrl+V
(e.keyCode === 88 && e.ctrlKey === true) || // Allow: Ctrl+X
(e.keyCode === 65 && e.metaKey === true) || // Cmd+A (Mac)
(e.keyCode === 67 && e.metaKey === true) || // Cmd+C (Mac)
(e.keyCode === 86 && e.metaKey === true) || // Cmd+V (Mac)
(e.keyCode === 88 && e.metaKey === true) || // Cmd+X (Mac)
(e.keyCode >= 35 && e.keyCode <= 39) // Home, End, Left, Right
) {
return; // let it happen, don't do anything
}
if (rgx.test(e['key']) == false) {
e.preventDefault();
}
};
let inputs = document.querySelectorAll('label-input[numberOnly] input, cbx-label-input[numberOnly] input')
//console.log(inputs)
inputs.forEach(i => (i as HTMLInputElement).onkeydown = preventNonNumber)
}
请注意,每次触摸输入都会触发ngAfterContentChecked,因此选择器将再次运行,并同时设置函数,但是由于它是一个静态函数,因此您只需重写就不会有太多性能问题。