O renderizador foi descontinuado no Angular 4.0.0-rc.1, leia a atualização abaixo
A maneira angular2 é usar listen
ou listenGlobal
do Renderer
Por exemplo, se você deseja adicionar um evento de clique a um Componente, é necessário usar o Renderer e ElementRef (isso também oferece a opção de usar o ViewChild ou qualquer coisa que recupere o nativeElement
)
constructor(elementRef: ElementRef, renderer: Renderer) {
// Listen to click events in the component
renderer.listen(elementRef.nativeElement, 'click', (event) => {
// Do something with 'event'
})
);
Você pode usar listenGlobal
que lhe dará acesso a document
, body
, etc.
renderer.listenGlobal('document', 'click', (event) => {
// Do something with 'event'
});
Observe que, desde o beta.2 ambos listen
e listenGlobal
retorne uma função para remover o ouvinte (consulte a seção de alterações recentes do changelog para o beta.2). Isso é para evitar vazamentos de memória em grandes aplicativos (consulte # 6686 ).
Portanto, para remover o ouvinte que adicionamos dinamicamente, devemos atribuir listen
ou listenGlobal
a uma variável que reterá a função retornada e depois a executamos.
// 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();
}
Aqui está um plnkr com um exemplo de trabalho. O exemplo contém o uso de listen
e listenGlobal
.
Usando o RendererV2 com Angular 4.0.0-rc.1 + (Renderer2 desde 4.0.0-rc.3)
25/02/2017 : Renderer
foi descontinuado, agora devemos usar RendererV2
(veja a linha abaixo). Veja o commit .
10/03/2017 : RendererV2
renomeado para Renderer2
. Veja as mudanças mais recentes .
RendererV2
não tem mais listenGlobal
função para eventos globais (documento, corpo, janela). Ele tem apenas uma listen
função que atinge ambas as funcionalidades.
Para referência, estou copiando e colando o código fonte da implementação do DOM Renderer, pois ele pode mudar (sim, é angular!).
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;
}
Como você pode ver, agora verifica se estamos passando uma string (documento, corpo ou janela); nesse caso, ele usará uma addGlobalEventListener
função interna . Em qualquer outro caso, quando passarmos um elemento (nativeElement), ele usará um simplesaddEventListener
Para remover o ouvinte, é igual Renderer
ao angular 2.x. listen
retorna uma função e chame essa função.
Exemplo
// 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 com Angular 4.0.0-rc.1 usando RendererV2
plnkr com Angular 4.0.0-rc.3 usando o Renderer2
host
é usado também.ngOnDestroy
código, amboslisten
elistenGlobal
retornam uma função que, quando chamada / executada, o ouvinte é removido. Então, como você vê,this.func
está mantendo a função retornada porrenderer.listen
e, quando o façothis.func()
, estou removendo o ouvinte. O mesmo vale paralistenGlobal
.Eu também acho isso extremamente confuso. como @EricMartinez aponta Renderer2 listen () retorna a função para remover o ouvinte:
Se estou adicionando um ouvinte
Eu esperaria que minha função execute o que eu pretendia, não o total oposto ao qual é remover o ouvinte.
No cenário fornecido, faria mais sentido nomear como:
Deve haver uma boa razão para isso, mas, na minha opinião, é muito enganador e não intuitivo.
fonte
ngOnDestroy
método. Admito que possa parecer confuso a princípio, mas na verdade é um recurso muito útil. De que outra forma você se limpa?Vou adicionar um exemplo StackBlitz e um comentário à resposta de @tahiche.
O valor de retorno é uma função para remover o ouvinte de evento após a adição. É considerado uma boa prática remover ouvintes de eventos quando você não precisar mais deles. Portanto, você pode armazenar esse valor de retorno e chamá-lo dentro do seu
ngOnDestroy
método.Admito que possa parecer confuso a princípio, mas na verdade é um recurso muito útil. De que outra forma você pode se limpar?
Você pode encontrar um StackBlitz aqui para mostrar como isso poderia funcionar para capturar cliques em elementos âncora.
Adicionei um corpo com uma imagem da seguinte forma:
<img src="x" onerror="alert(1)"></div>
para mostrar que o desinfetante está fazendo seu trabalho.
Aqui neste violino, você encontra o mesmo corpo ligado a um
innerHTML
sem higienizá-lo e ele demonstrará o problema.fonte
Aqui está minha solução alternativa:
Criei uma biblioteca com o Angular 6. Adicionei um componente comum
commonlib-header
que é usado assim em um aplicativo externo.Observe
serviceReference
qual é a classe (injetada no componenteconstructor(public serviceReference: MyService)
que usa ocommonlib-header
) que contém ostringFunctionName
método:O componente da biblioteca é programado assim. O evento dinâmico é adicionado no
onClick(fn: any)
método:O reutilizável
header.component.html
:fonte