2017-06-06 7 views
0

Ich habe diese Button-Klasse in Typoskript gemacht. Ich habe es eine "Standard" -Funktion gegeben, um Klickereignisse zu behandeln. Was aber, wenn ich stattdessen eine Funktion als Argument übergeben und stattdessen die übergebene auf Klick aufrufen möchte?Standardfunktion in Typoskript-Klasse überschreiben

Hier ist der Code:

abstract class BaseButton { 

    element:HTMLElement; 
    label:string; 

    constructor(element:HTMLElement, label:string) { 
    console.log(this); 
    this.element = element; 
    this.label = label; 
    this.init(); 
    } 

    init():void { 
    this.setText(this.label); 
    this.addListeners(); 
    } 

    setText(label:string):void { 
    this.element.innerHTML = label; 
    } 

    kill():void { 
    this.removeListeners(); 
    } 

    addListeners():void { 
    this.element.addEventListener("mouseover", this.onMouseOver); 
    this.element.addEventListener("click", this.onClick); 
    this.element.addEventListener("mouseout", this.onMouseOut); 
    this.element.addEventListener('touchstart', this.onTouchStart); 
    this.element.addEventListener('touchmove', this.onTouchMove); 
    this.element.addEventListener('touchcancel', this.onTouchCancel); 
    this.element.addEventListener('touchend', this.onTouchEnd); 
    } 

    removeListeners():void { 
    this.element.removeEventListener("mouseover", this.onMouseOver); 
    this.element.removeEventListener("click", this.onClick); 
    this.element.removeEventListener("mouseout", this.onMouseOut); 
    this.element.removeEventListener('touchstart', this.onTouchStart); 
    this.element.removeEventListener('touchmove', this.onTouchMove); 
    this.element.removeEventListener('touchcancel', this.onTouchCancel); 
    this.element.removeEventListener('touchend', this.onTouchEnd); 
    } 

    onTouchStart():void { 

    } 

    onTouchMove():void { 

    } 

    onTouchCancel():void { 

    } 

    onTouchEnd():void { 

    } 

    onMouseOver():void { 
    console.log('mouse over'); 
    } 

    onMouseOut():void { 
    console.log('mouse out'); 
    } 

    abstract onClick(event:Event):void 
} 

class Button extends BaseButton { 

    element:HTMLElement; 
    label:string; 
    callback:any; 

    constructor(element:HTMLElement, label:string, callback?:() => void) { 
    super(element,label); 
    this.element = element; 
    this.label = label; 
    this.callback = callback; 
    } 

    onClick(event:Event):void { 
    if (this.callback) { 
     console.log('ddd'); 
     this.callback(); 
    } 
    } 
} 





const el = document.getElementById('btn'); 
const button = new Button(el,'Click'); 

const ell = document.getElementById('btnn'); 
const buttonn = new Button(ell,'Click'); 

const elll = document.getElementById('btnnn'); 
const buttonnn = new Button(elll,'Click',() => { 
    alert('fff'); 
}); 

Antwort

0

Sie verlieren die this Referenz innerhalb der onClick Funktion der Unterklasse, wenn die folgende Ereignisbehandlungsroutine in der Basisklasse läuft:

this.element.addEventListener("click", this.onClick) 

Normalerweise könnte dies mit einer Pfeilfunktion gelöst werden:

class Button extends BaseButton { 
    constructor(element: HTMLElement, label: string, private callback?:() => void) { 
    super(element, label); 
    } 

    onClick = (event: Event) => { 
    if (this.callback) { 
     this.callback(); 
    } 
    } 
} 

Aber in diesem speziellen Fall erhalten Sie die folgende Fehlermeldung erhalten, wenn Sie versuchen, es in der Unterklasse zu definieren:

Class 'BaseButton' defines instance member function 'onClick', but extended class 'Button' defines it as instance member property.

Und wenn Sie versuchen, eine onClick Pfeil Funktion in der Unterklasse Konstruktor zu definieren:

class Button extends BaseButton { 
    constructor(element: HTMLElement, label: string, private callback?:() => void) { 
    super(element, label); 

    this.onClick =() => { 
     // ... 
    } 
    } 
} 

Sie folgende Fehlermeldung erhalten:

Non-abstract class 'Button' does not implement inherited abstract member 'onClick' from class 'BaseButton'

und wenn Sie nur versuchen, ein Stub-Methode erstellen die Fehler verschwinden zu machen, und erstellen Sie die Real Verfahren als Pfeil Funktion im Konstruktor:

class Button extends BaseButton { 
    constructor(element: HTMLElement, label: string, private callback?:() => void) { 
    super(element, label); 

    this.onClick =() => { 
     // ... 
    } 
    } 

    onClick(event: Event) { } 
} 

Es wird nicht funktionieren, weil die Basisklasse für den falschen onClick Funktion Verweis auf addEventListener passieren würde, weil dieser Code vor der Konstruktor der Unterklasse ausgeführt wird.

Hier ist eine Problemumgehung. Binden Sie this in der Basisklasse ein, indem Sie dort eine separate Funktion erstellen, die this.onClick() aufruft, und behalten Sie einen Verweis auf diese neue Funktion, damit Sie sie abmelden können.

Ich werde versuchen, mit einer saubereren Lösung zu kommen, da ich nicht verrückt nach diesem bin.

+0

Hallo, danke! Vielleicht war ich nicht klar genug. Was ich tun möchte, ist über den Klick in der Schaltfläche zu überschreiben, wenn ein Click-Handler als Argument übergeben wird. – user2952238

+0

Ich glaube, dass mein Code das tut, was Sie fragen. Lassen Sie mich wissen, wenn Sie Änderungen benötigen. –

+0

Es gibt mir den folgenden Fehler: TypeError: this. clickHandler ist keine Funktion. – user2952238

0

Was ist, wenn Sie so etwas gemacht haben (mit dem Rest Ihres Codes hinzugefügt)?

class Button { 
    clickListener; // with any types 

    constructor(clickListener = defaultClickListener) { 
     this.clickListener = clickListener; 
     this.clickListener(); 
    } 
} 

function defaultClickListener():void { 
    console.log(0); 
} 

new Button(() => console.log(1)); 
Verwandte Themen