简体   繁体   English

从打字稿类发出不是Angular组件的angular2事件

[英]Emit angular2 event from a typescript class that is **not** an angular component

I am building an interactive web app, and the core part of my webpage is an angular component, interactionStage.component , which houses a typescript class InteractionStage.ts . 我正在构建一个交互式Web应用程序,并且我网页的核心部分是一个有角组件, interactionStage.component ,其中包含一个打字稿类InteractionStage.ts The latter, as it's name implies, is a graphical "stage" which users can interact with, it listens for and responds to a number of mouse events which are important in the context of the stage. 顾名思义,后者是一个图形“阶段”,用户可以与之交互,侦听并响应在此阶段上下文中很重要的许多鼠标事件。

Omitting unnecessary details, my interactionStage.component looks like this: 省略不必要的细节,我的interactionStage.component看起来像这样:

@Component({
    selector: 'interaction-stage',
    templateUrl: './interactionStage.component.html',
    styleUrls: ['./interactionStage.component.css'],
})
export class InteractionStage.component implements OnInit {
    private stage : InteractionStage;

    constructor(){
        this.stage = new InteractionStage();
    }

    catchImportantEvent($event) {
        console.log($event);
        //Do stuff with the event data
    }
}

There's not much to show, but just to give you some context, my InteractionStage class looks like this: 没有太多要显示的内容,但是只是为了给您一些上下文,我的InteractionStage类看起来像这样:

export class InteractionStage {

    constructor(){
        //initialize important stuff here
    }

    public emitImportantEvent() {
        //TODO: emit an event so that interactionStage.component receives it
    }
}

Given the nature of InteractionStage , it needs to be able to emit events when an action happens on it, for example to notify a user of something, display a modal, or to alter the DOM. 鉴于InteractionStage的性质,它需要能够在发生操作时发出事件,例如,向用户通知某些内容,显示模式或更改DOM。 These events need to be received by InteractionStage.component , and in the future, might need to be received by other angular components on the page. 这些事件需要由InteractionStage.component接收,将来,可能需要由页面上的其他角度组件接收。

The problem I'm facing is is emitting these events from InteractionStage . 我面临的问题是从InteractionStage发出这些事件。 I know how to emit and catch events using angular components, by using the @Output notation. 我知道如何使用@Output符号使用角度分量来发出和捕获事件。 As a stab in the dark, I tried using that in my InteractionStage class: 作为在黑暗中的刺伤,我尝试在InteractionStage类中使用它:

import { Output, EventEmitter } from '@angular/core';

export class InteractionStage {

    @Output importantEvent: EventEmitter<any> new EventEmitter();

    constructor(){
        //initialize important stuff here
    }

    public emitImportantEvent() {
        var importantData = "here is a very important string";
        this.importantEvent.emit(importantData);
    }
}

Then I tried to catch this event in my InteractionStage.component like this: 然后,我试图在我的InteractionStage.component捕获此事件,如下所示:

 <interaction-stage (importantEvent)=catchImportantEvent($event)></interaction-stage>

But, absolutely nothing happens. 但是,绝对没有任何反应。 No event is received and nothing is logged to the console. 没有接收到事件,也没有任何日志记录到控制台。

Am I doing something wrong, or is what I'm trying to do impossible? 我是在做错什么,还是我想做的是不可能的? If it can't be done, how else can I send an event from a typescript file and have it caught by an angular component? 如果无法完成,该如何从打字稿文件发送事件并使其被角度组件捕获?

I realise I can pass a reference of InteractionStage.component into the constructor of InteractionStage , but I think that's a code smell - coupling that is unneccesary. 我知道我可以传递的参考InteractionStage.component到的构造InteractionStage ,但我认为这是一个代码味道-耦合是unneccesary。 The interaction stage should not know about the angular component that holds it. 交互阶段不应该知道保持它的角度分量。

@Component({
selector: 'interaction-stage',
    templateUrl: './interactionStage.component.html',
    styleUrls: ['./interactionStage.component.css'],
})
export class InteractionStageComponent implements OnInit {
    private stage : InteractionStage;
    @Output myEmitter: EventEmitter<any> = new EventEmitter<any>();

    constructor(){
        this.stage = new InteractionStage(myEmitter);
    }

    catchImportantEvent($event) {
        console.log($event);
        //Do stuff with the event data
    }
}

export class InteractionStage {

    constructor(private myEmitter: EventEmitter<any>){
        //initialize important stuff here
    }

    public emitImportantEvent() {
      this.myEmitter.emit("my data");
        //TODO: emit an event so that interactionStage.component receives it
    }
}

I also changed InteractionStage.component to InteractionStageComponent because the angularCLI generates it like that so I assume its a practice 我也将InteractionStage.component更改为InteractionStageComponent,因为angularCLI会像这样生成它,所以我假设它是一种实践

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM