2016-07-20 14 views
7

Ich versuche eine Angular2-Attribut-Direktive zu schreiben, um das Verhalten bestimmter Elemente zu modifizieren. Genauer gesagt möchte ich ein Attribut auf bestimmte Elemente anwenden, die Click-Handler haben und verhindern, dass die gebundene Funktion unter bestimmten Bedingungen ausgeführt wird.Angular2 Direktive zum Ändern der Klick-Handhabung

So, jetzt habe ich ein Element z.B .:

<button (click)="onClick(param1, param2)"></button> 

onClick eine Funktion auf die Komponente deklariert ist, die die Schaltfläche Element dabei einige Arbeit ausrichtet.

Was würde ich tun möchte, ist wie etwas schreiben:

<button (click)="onClick(param1, param2)" online-only></button> 

und eine Richtlinie haben wie:

@Directive({ 
    selector: '[online-only]', 
}) 
export class OnlineOnlyDirective { 
    @HostListener('click', ['$event']) 
    onClick(e) { 
    if(someCondition){ 
     e.preventDefault(); 
     e.stopPropagation(); 
    } 
    } 
} 

Aber klicken Handler wird zuerst ausgeführt, also nicht meine Richtlinie geben die Möglichkeit, Stoppen Sie die Ausführung. Ein zweiter Ansatz, über den ich nachdachte, war das Ersetzen (Klicken) mit meinem eigenen Handler zB ([onlineClick] = "onClick") und Ausführen der übergebenen Funktion, wenn die Direktive dies für richtig hält, aber auf diese Weise kann ich keine Parameter an onClick übergeben und ist ein bisschen seltsamer anzusehen.

Haben Sie irgendwelche Gedanken darüber, so etwas zu tun?

Antwort

8

Ich kenne keine Möglichkeit, Angular zu zwingen, einen bestimmten Event-Handler zuerst auszuführen. Eine Abhilfe könnte sein, ein benutzerdefiniertes Ereignis zu verwenden wie:

<button (myClick)="onClick(param1, param2)" online-only></button> 
@Directive({ 
    selector: '[myClick]', 
}) 
export class OnlineOnlyDirective { 
    @Output() myClick: EventEmitter = new EventEmitter(); 
    @HostListener('click', ['$event']) 
    onClick(e) { 
    if(someCondition){ 
     e.preventDefault(); 
     e.stopPropagation(); 
    } else { 
     this.myClick.next(e); 
    } 
    } 
} 
+0

Yeap, viel besser auf meinem beschriebenen zweiten Ansatz. Die Verwendung eines EventEmitter, anstatt die Aufruffunktion zu übergeben, macht den Unterschied. Der erste Ansatz wäre eleganter, wird aber wahrscheinlich nicht von angular2 unterstützt, wie Sie auch sagten. – masimplo

+1

Nur neugierig, ob der Selektor "nur online" sein sollte? Versuchen herauszufinden, was mit dieser Richtlinie passiert ist. –

+0

Ich weiß nicht, ob oder wie 'only-only' mit der Frage verwandt ist –

1

Bisher ist dies nicht möglich, in einer Art und Weise wollte man das tun (nur mit (click) Bindung). Dies liegt daran, dass alle Ereignisse, die via Angular -> by (click) Binding, @HostListner registriert wurden, über einen einzelnen Listener weitergeleitet werden. Deshalb funktioniert das Aufrufen von stopPropagation oder besser in diesem Fall stopImmediatePropagation nicht, da Sie keine separaten Ereignis-Listener mehr haben. Bitte beachten Sie dieses Problem für weitere Details: https://github.com/angular/angular/issues/9587.

Verwandte Themen