Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript支持类上的事件吗?_Typescript - Fatal编程技术网

TypeScript支持类上的事件吗?

TypeScript支持类上的事件吗?,typescript,Typescript,我只是想知道在TypeScript中是否可以在类或接口上定义自定义事件 这是什么样子的 您可以在TypeScript中使用自定义事件。我不确定你到底想做什么,但这里有一个例子: module Example { export class ClassWithEvents { public div: HTMLElement; constructor (id: string) { this.div = document.getEleme

我只是想知道在TypeScript中是否可以在类或接口上定义自定义事件


这是什么样子的

您可以在TypeScript中使用自定义事件。我不确定你到底想做什么,但这里有一个例子:

module Example {
    export class ClassWithEvents {
        public div: HTMLElement;

        constructor (id: string) {
            this.div = document.getElementById(id);

            // Create the event
            var evt = document.createEvent('Event');
            evt.initEvent('customevent', true, true);

            // Create a listener for the event
            var listener = function (e: Event) {
                var element = <HTMLElement> e.target;
                element.innerHTML = 'hello';
            }

            // Attach the listener to the event
            this.div.addEventListener('customevent', listener);

            // Trigger the event
            this.div.dispatchEvent(evt);
        }
    }
}
模块示例{
导出类类WithEvents{
公共事务组:民政事务;;
构造函数(id:string){
this.div=document.getElementById(id);
//创建事件
var evt=document.createEvent('Event');
evt.initEvent('customevent',true,true);
//为事件创建侦听器
var listener=函数(e:事件){
var元素=e.目标;
element.innerHTML='hello';
}
//将侦听器附加到事件
this.div.addEventListener('customevent',listener);
//触发事件
本部门调度事件(evt);
}
}
}

如果您想做一些更具体的事情,请告诉我。

我想您是在问类实例是否可以像DOM元素一样实现addEventListener()和dispatchEvent()。如果该类不是DOM节点,则必须编写自己的事件总线。您可以为可以发布事件的类定义一个接口,然后在类中实现该接口。这是一个天真的例子

interface IEventDispatcher{
  // maintain a list of listeners
  addEventListener(theEvent:string, theHandler:any);

  // remove a listener
  removeEventListener(theEvent:string, theHandler:any);

  // remove all listeners
  removeAllListeners(theEvent:string);

  // dispatch event to all listeners
  dispatchAll(theEvent:string);

  // send event to a handler
  dispatchEvent(theEvent:string, theHandler:any);
}

class EventDispatcher implement IEventDispatcher {
  private _eventHandlers = {};

  // maintain a list of listeners
  public addEventListener(theEvent:string, theHandler:any) {
    this._eventHandlers[theEvent] = this._eventHandlers[theEvent] || [];
    this._eventHandlers[theEvent].push(theHandler);
  }

  // remove a listener
  removeEventListener(theEvent:string, theHandler:any) {
    // TODO
  }

  // remove all listeners
  removeAllListeners(theEvent:string) {
    // TODO
  }

  // dispatch event to all listeners
  dispatchAll(theEvent:string) {
    var theHandlers = this._eventHandlers[theEvent];
    if(theHandlers) {
      for(var i = 0; i < theHandlers.length; i += 1) {
        dispatchEvent(theEvent, theHandlers[i]);
      }
    }
  }

  // send event to a handler
  dispatchEvent(theEvent:string, theHandler:any) {
    theHandler(theEvent);
  }
}
接口IEventDispatcher{
//维护侦听器列表
addEventListener(事件:字符串,处理程序:任意);
//删除侦听器
removeEventListener(事件:字符串,处理程序:任意);
//删除所有侦听器
移除所有侦听器(事件:字符串);
//将事件分派给所有侦听器
dispatchAll(事件:字符串);
//将事件发送到处理程序
dispatchEvent(事件:字符串,处理程序:任意);
}
类EventDispatcher实现IEventDispatcher{
私有_eventHandlers={};
//维护侦听器列表
公共addEventListener(事件:字符串,处理程序:任意){
此._eventHandlers[theEvent]=此._eventHandlers[theEvent]| |[];
此.u事件处理程序[theEvent].push(theHandler);
}
//删除侦听器
removeEventListener(事件:字符串,处理程序:任意){
//待办事项
}
//删除所有侦听器
removeAllListeners(事件:字符串){
//待办事项
}
//将事件分派给所有侦听器
dispatchAll(事件:字符串){
var theHandlers=this.\u eventHandlers[theEvent];
如果(处理程序){
对于(变量i=0;i
将此简化事件用作属性如何?所属类的类型更强,且无继承要求:

interface ILiteEvent<T> {
    on(handler: { (data?: T): void }) : void;
    off(handler: { (data?: T): void }) : void;
}

class LiteEvent<T> implements ILiteEvent<T> {
    private handlers: { (data?: T): void; }[] = [];

    public on(handler: { (data?: T): void }) : void {
        this.handlers.push(handler);
    }

    public off(handler: { (data?: T): void }) : void {
        this.handlers = this.handlers.filter(h => h !== handler);
    }

    public trigger(data?: T) {
        this.handlers.slice(0).forEach(h => h(data));
    }

    public expose() : ILiteEvent<T> {
        return this;
    }
}
接口ILiteEvent{
on(处理程序:{(数据?:T):void}):void;
off(处理程序:{(数据?:T):void}):void;
}
类LiteEvent实现ILiteEvent{
私有处理程序:{(数据?:T):void;}[]=[];
public on(处理程序:{(数据?:T):void}):void{
this.handlers.push(handler);
}
公共关闭(处理程序:{(数据?:T):void}):void{
this.handlers=this.handlers.filter(h=>h!==handler);
}
公共触发器(数据?:T){
this.handlers.slice(0).forEach(h=>h(数据));
}
public expose():ILiteEvent{
归还这个;
}
}
这样使用:

class Security{
    private readonly onLogin = new LiteEvent<string>();
    private readonly onLogout = new LiteEvent<void>();

    public get LoggedIn() { return this.onLogin.expose(); } 
    public get LoggedOut() { return this.onLogout.expose(); }

    // ... onLogin.trigger('bob');
}

function Init() {
    var security = new Security();

    var loggedOut = () => { /* ... */ }

    security.LoggedIn.on((username?) => { /* ... */ });
    security.LoggedOut.on(loggedOut);

    // ...

    security.LoggedOut.off(loggedOut);
}
类安全性{
private readonly onLogin=new LiteEvent();
private readonly onLogout=new LiteEvent();
public get LoggedIn(){返回this.onLogin.expose();}
public get LoggedOut(){返回this.onLogout.expose();}
//…onLogin.trigger('bob');
}
函数Init(){
var security=newsecurity();
变量loggedOut=()=>{/*…*/}
security.LoggedIn.on((用户名?=>{/*…*/});
security.LoggedOut.on(LoggedOut);
// ...
security.LoggedOut.off(LoggedOut);
}
改进


此解决方案允许您直接在函数调用中写入参数,而无需将所有参数包装到对象中

interface ISubscription {
   (...args: any[]): void;
}

class PubSub<T extends ISubscription> {
    protected _subscribed : ISubscriptionItem[] = [];

    protected findSubscription(event : T) : ISubscriptionItem {
        this._subscribed.forEach( (item : ISubscriptionItem) =>{
            if (item.func==event)
              return item;
        } );
        return null;
    }

    public sub(applyObject : any,event : T) {
        var newItem = this.findSubscription(event);
        if (!newItem) {
            newItem = {object : applyObject, func : event };
            this._subscribed.push(newItem);
            this.doChangedEvent();
        }
    }
    public unsub(event : T) {
        for ( var i=this._subscribed.length-1 ; i>=0; i--) {
            if (this._subscribed[i].func==event)
                this._subscribed.splice(i,1);
        }
        this.doChangedEvent();
    }
    protected doPub(...args: any[]) {
        this._subscribed.forEach((item : ISubscriptionItem)=> {
            item.func.apply(item.object, args);
        })
    }

    public get pub() : T {
        var pubsub=this;
        var func=  (...args: any[]) => {
            pubsub.doPub(args);
        }
        return <T>func;
    }

    public get pubAsync() : T {
        var pubsub=this;
        var func =  (...args: any[]) => {
            setTimeout( () => {
                pubsub.doPub(args);
            });
        }
        return <T>func;
    }

    public get count() : number {
        return this._subscribed.length
    }

}
接口订阅{
(…args:any[]):无效;
}
类PubSub{
受保护的订阅:ISubscriptionItem[]=[];
受保护的findSubscription(事件:T):ISubscriptionItem{
此._subscribed.forEach((项目:ISubscriptionItem)=>{
if(item.func==事件)
退货项目;
} );
返回null;
}
公共子对象(应用对象:任意,事件:T){
var newItem=this.findSubscription(事件);
如果(!newItem){
newItem={object:applyObject,func:event};
此._订阅推送(newItem);
this.doChangedEvent();
}
}
公共不明嫌犯(事件:T){
对于(var i=此。_subscribed.length-1;i>=0;i--){
if(this._订阅[i].func==事件)
这是一个接头(i,1);
}
this.doChangedEvent();
}
受保护的doPub(…参数:任意[]){
此._subscribed.forEach((项目:ISubscriptionItem)=>{
item.func.apply(item.object,参数);
})
}
public get pub():T{
var pubsub=此;
var func=(…参数:任意[])=>{
pubsub.doPub(args);
}
返回函数;
}
public get pubAsync():T{
var pubsub=此;
var func=(…参数:任意[])=>{
设置超时(()=>{
pubsub.doPub(args);
});
}
返回函数;
}
public get count():number{
返回此。\u.length
}
}
用法:

interface ITestEvent {
    (test : string): void;
}

var onTestEvent = new PubSub<ITestEvent>();
//subscribe to the event
onTestEvent.sub(monitor,(test : string) => {alert("called:"+test)});
//call the event
onTestEvent.pub("test1");
interface-ITestEvent{
(测试:字符串):无效;
}
var onTestEvent=new PubSub();
//订阅活动
sub(监视器,(测试:字符串)=>{alert(“调用:“+test”);
//召集这次活动
onTestEvent.pub(“test1”);

如果您希望获得智能感知类型c
type DataEventType = "data";
type ErrorEventType = "error";
declare interface IDataStore<TResponse> extends Emitter {
    on(name: DataEventType, handler : (data: TResponse) => void);   
    on(name: ErrorEventType, handler: (error: any) => void);    
}
interface IEventHandler<TSender, TArgs> {
    (sender: TSender, args: TArgs): void
}

interface ISimpleEventHandler<TArgs> {
    (args: TArgs): void
}

interface ISignalHandler {
    (): void;
}
class Clock {

    //implement events as private dispatchers:
    private _onTick = new SignalDispatcher();
    private _onSequenceTick = new SimpleEventDispatcher<number>();
    private _onClockTick = new EventDispatcher<Clock, number>();

    private _ticks: number = 0;

    constructor(public name: string, timeout: number) {
        window.setInterval( () => { 
            this.Tick(); 
        }, timeout);
    }

    private Tick(): void {
        this._ticks += 1;

        //trigger event by calling the dispatch method and provide data
        this._onTick.dispatch();
        this._onSequenceTick.dispatch(this._ticks);
        this._onClockTick.dispatch(this, this._ticks);
    }

    //expose the events through the interfaces - use the asEvent
    //method to prevent exposure of the dispatch method:
    public get onTick(): ISignal {
        return this._onTick.asEvent();
    }

    public get onSequenceTick() : ISimpleEvent<number>{
        return this._onSequenceTick.asEvent();
    }

    public get onClockTick(): IEvent<Clock, number> {
        return this._onClockTick.asEvent();
    }
}
let clock = new Clock('Smu', 1000);

//log the ticks to the console
clock.onTick.subscribe(()=> console.log('Tick!'));

//log the sequence parameter to the console
clock.onSequenceTick.subscribe((s) => console.log(`Sequence: ${s}`));

//log the name of the clock and the tick argument to the console
clock.onClockTick.subscribe((c, n) => console.log(`${c.name} ticked ${n} times.`))
class MyClass {

    readonly onMessage: SubEvent<string> = new SubEvent();
    readonly onData: SubEvent<MyCustomType> = new SubEvent();

    sendMessage(msg: string) {
        this.onMessage.emit(msg);
    }

    sendData(data: MyCustomType) {
        this.onData.emit(data);
    }
}
const a = new MyClass();

const sub1 = a.onMessage.subscribe(msg => {
    // msg here is strongly-typed
});

const sub2 = a.onData.subscribe(data => {
    // data here is strongly-typed
});
sub1.cancel();

sub2.cancel();
export class MyClass {
    private _eventSubject = new Subject();
   
    public events = this._eventSubject.asObservable();

    public dispatchEvent(data: any) {
        this._eventSubject.next(data);
    }
}
let myClassInstance = new MyClass();
myClassInstance.dispatchEvent(data);
myClassInstance.events.subscribe((data: any) => { yourCallback(); });