[英]How to communicate from the child component to parent attribute directive in Angular 7?
我的目标是让自定义指令在其范围内侦听 DOM 事件; 并处理该事件。 在这种情况下,DOMEvent 将发生在我无法控制的第三方组件中。
在 Angular 中,我在组件中定义了以下模板。
该模板有一个指令(称为my-directive
),它与 ckeditor 组件的 keypress 事件挂钩。
我不拥有 ckeditor 的代码; 并且我试图避免不必更改任何代码,以便这可以成为一个可重用的钩子。
<!-- lots of irrelevant template code snipped -->
<my-directive>
<ckeditor [editor]="Editor" (keypress)="pressed($event)"></ckeditor>
</my-directive>
<!-- lots of irrelevant template code snipped -->
my.directive.ts
定义如下:
import { Directive, OnInit } from "@angular/core";
@Directive({
selector: 'my-directive',
})
export class MyDirective implements OnInit {
public pressed(e: Event) : void {
console.table(e);
}
constructor(
) { }
ngOnInit() : void {
}
}
而 CKEditor 来自 angular-ckeditor 包; 使用以下导入:
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
当我尝试从 ckeditor 标签调用被pressed
函数时; 它抱怨pressed
不是一个功能:
exception-handler.ts:41 TypeError: _co.pressed is not a function
at Object.eval [as handleEvent] (SomeComponent.html:60)
at handleEvent (core.js:21673)
at callWithDebugContext (core.js:22767)
at Object.debugHandleEvent [as handleEvent] (core.js:22470)
at dispatchEvent (core.js:19122)
at core.js:19569
at HTMLUnknownElement.<anonymous> (platform-browser.js:993)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:16147)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422) "/myurl/1"
也许问题是 Angular 试图在ckeditor
上调用ckeditor
pressed()
?
所以我尝试使用模板引用变量:
<!-- lots of irrelevant template code snipped -->
<my-directive #md>
<ckeditor [editor]="Editor" (keypress)="md.pressed($event)"></ckeditor>
</my-directive>
<!-- lots of irrelevant template code snipped -->
所以我得到了这个错误:
TypeError: jit_nodeValue_4(...).pressed is not a function
at Object.eval [as handleEvent] (SomeComponent.html:60)
at handleEvent (core.js:21673)
at callWithDebugContext (core.js:22767)
at Object.debugHandleEvent [as handleEvent] (core.js:22470)
at dispatchEvent (core.js:19122)
at core.js:19569
at HTMLUnknownElement.<anonymous> (platform-browser.js:993)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:16147)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422) "/myurl/1"
归根结底,我的问题是:
如何允许指令响应子组件中引发的标准 DOM 事件?
我不想修改子组件; 在某些情况下我不能(这不是我的代码)。 我希望可以将此指令添加到其他组件的模板中,并且不必在内部修改这些组件以允许此指令实现的新行为。
经过更多的调查; 似乎通过附加到子组件的模板声明来收听标准 DOM 事件是多余的,我可以通过执行以下操作来实现我想要的:
@HostListener
添加到MyDirective
:import { Directive, OnInit } from "@angular/core";
@Directive({
selector: 'my-directive',
})
export class MyDirective implements OnInit {
public pressed(e: Event) : void {
}
@HostListener('keypress') onKeyPress(e: Event) {
console.table(e);
}
constructor(
) { }
ngOnInit() : void {
}
}
my-directive
声明包裹在孩子周围:<!-- lots of irrelevant template code snipped -->
<my-directive>
<ckeditor [editor]="Editor"></ckeditor>
</my-directive>
<!-- lots of irrelevant template code snipped -->
现在,如果在my-directive
标签内发生任何按键事件(无论是它还是它的子标签),它都会引发一个@HostListener
将响应的事件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.