Renderer est obsolète dans Angular 4.0.0-rc.1, lisez la mise à jour ci-dessous
La méthode angular2 consiste à utiliser listen
ou à listenGlobal
partir de Renderer
Par exemple, si vous souhaitez ajouter un événement de clic à un composant, vous devez utiliser Renderer et ElementRef (cela vous donne également la possibilité d'utiliser ViewChild, ou tout ce qui récupère le nativeElement
)
constructor(elementRef: ElementRef, renderer: Renderer) {
// Listen to click events in the component
renderer.listen(elementRef.nativeElement, 'click', (event) => {
// Do something with 'event'
})
);
Vous pouvez utiliser listenGlobal
qui vous donnera accès à document
, body
etc.
renderer.listenGlobal('document', 'click', (event) => {
// Do something with 'event'
});
Notez que depuis la version bêta.2 les deux listen
et listenGlobal
retournent une fonction pour supprimer l'écouteur (voir la section des changements de rupture du journal des modifications pour la version bêta.2). C'est pour éviter les fuites de mémoire dans les grosses applications (voir # 6686 ).
Donc, pour supprimer l'écouteur que nous avons ajouté dynamiquement, nous devons affecter listen
ou listenGlobal
à une variable qui contiendra la fonction retournée, puis nous l'exécutons.
// listenFunc will hold the function returned by "renderer.listen"
listenFunc: Function;
// globalListenFunc will hold the function returned by "renderer.listenGlobal"
globalListenFunc: Function;
constructor(elementRef: ElementRef, renderer: Renderer) {
// We cache the function "listen" returns
this.listenFunc = renderer.listen(elementRef.nativeElement, 'click', (event) => {
// Do something with 'event'
});
// We cache the function "listenGlobal" returns
this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
// Do something with 'event'
});
}
ngOnDestroy() {
// We execute both functions to remove the respectives listeners
// Removes "listen" listener
this.listenFunc();
// Removs "listenGlobal" listener
this.globalListenFunc();
}
Voici un plnkr avec un exemple de travail. L'exemple contient l'utilisation de listen
et listenGlobal
.
Utilisation de RendererV2 avec Angular 4.0.0-rc.1 + (Renderer2 depuis 4.0.0-rc.3)
25/02/2017 : Renderer
est obsolète, nous devrions maintenant l'utiliser RendererV2
(voir ligne ci-dessous). Voir le commit .
10/03/2017 : a RendererV2
été renommé en Renderer2
. Voir les changements de rupture .
RendererV2
n'a plus de listenGlobal
fonction pour les événements globaux (document, corps, fenêtre). Il n'a qu'une listen
fonction qui réalise les deux fonctionnalités.
Pour référence, je copie et colle le code source de l'implémentation du DOM Renderer car il peut changer (oui, c'est angulaire!).
listen(target: 'window'|'document'|'body'|any, event: string, callback: (event: any) => boolean):
() => void {
if (typeof target === 'string') {
return <() => void>this.eventManager.addGlobalEventListener(
target, event, decoratePreventDefault(callback));
}
return <() => void>this.eventManager.addEventListener(
target, event, decoratePreventDefault(callback)) as() => void;
}
Comme vous pouvez le voir, il vérifie maintenant si nous passons une chaîne (document, corps ou fenêtre), auquel cas il utilisera une addGlobalEventListener
fonction interne . Dans tous les autres cas, lorsque nous passons un élément (nativeElement), il utilisera un simpleaddEventListener
Pour supprimer l'auditeur, c'est la même chose qu'avec Renderer
angular 2.x. listen
renvoie une fonction, puis appelez cette fonction.
Exemple
// Add listeners
let global = this.renderer.listen('document', 'click', (evt) => {
console.log('Clicking the document', evt);
})
let simple = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {
console.log('Clicking the button', evt);
});
// Remove listeners
global();
simple();
plnkr avec Angular 4.0.0-rc.1 en utilisant RendererV2
plnkr avec Angular 4.0.0-rc.3 en utilisant Renderer2
host
est également utilisé.ngOnDestroy
code, les deuxlisten
etlistenGlobal
retournent une fonction qui, lorsqu'elle est appelée / exécutée, l'écouteur est supprimée. Donc, comme vous le voyez, ilthis.func
contient la fonction retournée parrenderer.listen
et quand je le fais,this.func()
je supprime l'écouteur. Il en va de mêmelistenGlobal
.Je trouve également cela extrêmement déroutant. comme @EricMartinez le souligne Renderer2 listen () renvoie la fonction pour supprimer l'écouteur:
Si j'ajoute un auditeur
Je m'attendrais à ce que ma fonction exécute ce que je voulais, pas le contraire total qui est de supprimer l'auditeur.
Dans le scénario donné, il serait en fait plus logique de le nommer comme suit:
Il doit y avoir une bonne raison à cela mais à mon avis c'est très trompeur et pas intuitif.
la source
ngOnDestroy
méthode. J'avoue que cela peut sembler déroutant au début, mais c'est en fait une fonctionnalité très utile. Sinon, comment nettoyer après vous-même?J'ajouterai un exemple StackBlitz et un commentaire à la réponse de @tahiche.
La valeur de retour est une fonction pour supprimer l'écouteur d'événements après l'avoir ajouté. Il est recommandé de supprimer les écouteurs d'événements lorsque vous n'en avez plus besoin. Vous pouvez donc stocker cette valeur de retour et l'appeler dans votre
ngOnDestroy
méthode.J'avoue que cela peut sembler déroutant au début, mais c'est en fait une fonctionnalité très utile. Sinon, comment pouvez-vous nettoyer après vous-même?
Vous pouvez trouver un StackBlitz ici pour montrer comment cela pourrait fonctionner pour capturer les clics sur les éléments d'ancrage.
J'ai ajouté un corps avec une image comme suit:
<img src="x" onerror="alert(1)"></div>
pour montrer que le désinfectant fait son travail.
Ici, dans ce violon, vous trouvez le même corps attaché à un
innerHTML
sans le désinfecter et cela démontrera le problème.la source
Voici ma solution de contournement:
J'ai créé une bibliothèque avec Angular 6. J'ai ajouté un composant commun
commonlib-header
qui est utilisé comme ça dans une application externe.Notez
serviceReference
quelle est la classe (injectée dans le composantconstructor(public serviceReference: MyService)
qui utilise lecommonlib-header
) qui contient lastringFunctionName
méthode:Le composant de bibliothèque est programmé comme ceci. L'événement dynamique est ajouté dans la
onClick(fn: any)
méthode:Le réutilisable
header.component.html
:la source