網站搜尋

javascript - 我如何在 TypeScript ES6 類別中擴展 Backbone.Events?


我正在嘗試把 Backbone 的 Events 屬性附加到 TypeScript 類上,然而當我這麼做時...

class Foo {
    constructor () {
        _.assign(this, Backbone.Events); // or _.extend()
        this.stopListening(this.otherInstance);
    }
}

let bar = new Foo();
bar.on("myevent", handler);

...我遇到這些編譯時錯誤:

  • Error TS2339: Property 'stopListening' does not exist on type 'Foo'.
  • Error TS2339: Property 'on' does not exist on type 'Foo'.

我對 TypeScript 如何處理這個不是很熟悉,但看起來像是它能應付的事情。

注意:正在尋找一個解決方案,這個方案易於應用到多個同樣需要 Backbone.Events 功能的類別(也就是說,我不想將所有 on, off, listenTo... 方法複製/粘貼,或使用某種奇怪的代理方式,給每個需要它們的類別)。

由於 Backbone.Events 只是一個物件,我無法使用一般的 ES6 語法來擴展它。例如:

class Foo extends Backbone.Events {}

有什麼想法?

答案#1

如果你使用 _.extend 而不是 _.assign,它將可以運作,

這裡是一個 Plunker

    class Foo {
      constructor () {
         _.extend(this, Backbone.Events);
      }
    }

    let bar : any = new Foo();

    bar.on("alert", function(msg) {
      alert("Triggered " + msg);
    });

    bar.trigger("alert", "an event");

更新了程式碼,使其不會產生編譯時錯誤。

更新

你可以創建一個類,它包含為 Backbone.Events 定義的所有函數,其構造函數可以擴展 Backbone.Events,這將重寫所有僅為智能感知和類型檢查而定義的方法。

已更新 Plunker

 class CustomEvents {
    constructor() {
      _.extend(this, Backbone.Events);
    }

    on(eventName: string, callback?: Function, context?: any): any { return; };
    off(eventName?: string, callback?: Function, context?: any): any { return; };
    trigger(eventName: string, ...args: any[]): any { return; };
    bind(eventName: string, callback: Function, context?: any): any { return; };
    unbind(eventName?: string, callback?: Function, context?: any): any { return; };

    once(events: string, callback: Function, context?: any): any { return; };
    listenTo(object: any, events: string, callback: Function): any { return; };
    listenToOnce(object: any, events: string, callback: Function): any { return; };
    stopListening(object?: any, events?: string, callback?: Function): any { return; };
  }

你可以像下面這樣用 CustomEvents 類擴展任何類,

  class Foo extends CustomEvents {
    constructor(){
      super(); 
    }
  }

答案#2

在 Backbone.Events 上,事件處理是附加在物件本身,而不是它的 .prototype 上,以下是你可以如何修正它的方法:

import {Events} from 'backbone';

interface IEventEmitter extends Events {
    emit(event: string, ...args: any[]);
}

function _EventEmitter() {}
_EventEmitter.prototype = Events;
_EventEmitter.prototype.emit = (Events as any).trigger;
export const EventEmitter: new() => IEventEmitter
    = _EventEmitter as any as new() => IEventEmitter;

現在將其作為繼承使用:

class Dog extends EventEmitter {

}

var dog = new Dog;
dog.on('bark', () => console.log('Dog just barked'));
dog.emit('bark');