Mostrando postagens com marcador Angular 7. Mostrar todas as postagens
Mostrando postagens com marcador Angular 7. Mostrar todas as postagens

domingo, 8 de setembro de 2019

Trabalhando com múltiplas versões do Node e Angular na mesma máquina


Nesse post eu vou trazer algo bem interessante que aprendi na minha primeira semana no novo emprego: como trabalhar com mais de uma versão do Node e do Angular na mesma máquina de forma simples.

Quem costuma trabalhar em projetos diferentes e por vezes com versões diferentes do Angular, sabe que este pode exigir versões diferentes do Node, e justamente para facilitar essa tarefa existem dois carinhas muito interessantes: um é o NVM e o outro o NPX. Na verdade, existe um projeto chamado NVM (Node Version Manager) para Linux/Mac e outro projeto homônimo para Windows. Já o NPX vem no próprio NPM.

Basicamente a tarefa do NVM é manter versões do Node diferentes instaladas na máquina, e ao dizer para ele qual usar (com o comando nvm use) ele vai preparar as variáveis de ambiente e disponibilizar a versão de forma transparente.

O uso da versão para Windows depois de instalado basicamente se resume a:

nvm install 10.16.3
nvm use 10.16.3

E a partir de uma versão selecionada do Node, escolhe-se a versão do Angular:

npm install @angular/cli@19

Segue o link para os projetos NVM:       

Versão para Windows:

Versão para Linux/Mac:

Agora vamos falar sobre o NPX. Como já mencionei ele vem com o NPM a partir da versão 5.2.x pelo que pesquisei, e o que ele faz é executar projetos a partir das libs do próprio projeto, onde estão os binários necessários, sem ter que instalar nada globalmente. É o package runner do npm. E caso algo que eu queira executar não exista na máquina, ele baixa e executa, depois apaga o que foi baixado para não deixar sujeira na máquina. Inclusive ele roda projetos diretamente a partir do GitHub.

Para instalar basta digitar:

npm install -g npx

          E como estamos falando de Angular, para executar os comandos basta colocar o npx na frente e pronto! Lembre-se! A partir de agora você não precisa mais instalar coisas globais, apenas nas dependências do seu projeto!

          Para rodar um projeto Angular então, basta de dentro do diretório do projeto executar:

npx ng serve

          Segue o link do projeto com exemplos e a documentação:         


          Abraços!

sábado, 27 de julho de 2019

Resolvendo problema CORS no Angular

Olá, hoje vou falar sobre o CORS – Cross-Origin Resource Sharing que significa compartilhamento de recursos de origem cruzada.

Antes era muito comum o uso de iFrames ou similares para fazer com que um site acessasse diretamente conteúdo de outros o que também era válido para aplicações web mais complexas, o problema é que isso começou a ser explorado por pessoas mal intencionadas para se passarem por um site ou serviço que não são e roubar informações ou outras atividades ilícitas. Então os navegadores começaram a “bloquear” esse tipo de coisa, validando antes se a origem tem acesso ao backend vindo de um IP diferente ou não configurado em uma digamos “White list”.

Trarar o CORS é obrigação do backend ou infra, mas é possível e também uma boa prática tratar no frontend. Para isso criamos um Proxy no nosso frontend. Como funciona um proxy? Ele recebe a requisição e a repassa com uma nova configuração de rede.

Vamos criar o nosso proxy, crie um arquivo chamado proxy.config.js no mesmo diretório em que se encontra o seu package.json  com o seguinte conteúdo:

{
"/api": {
    "target": "http://localhost:8080", //endereço do backend
    "secure": false
}
}
Agora configure dentro do seu angular.json o uso do proxy:
...
"defaults"
:{
     "serve":{
          "proxyConfig":"./proxy.config.js"
      }
...


Fonte:
Para ver todas as opções da configuração de proxy veja:
https://webpack.js.org/configuration/dev-server/#devserver-proxy

terça-feira, 19 de março de 2019

Criando uma biblioteca de componentes com Angular 7, utilizando em projetos externos e publicando no NPM


Frameworks JavaScript estão sempre mudando, e geralmente são mudanças complexas que nos obrigam a reaprender como fazemos as coisas. Não foi diferente com a questão da criação de bibliotecas do Angular, que até a versão 5 era apenas um projeto comum, o qual empacotávamos no formato NPM e publicávamos. Agora, a partir da versão 7 em diante o Angular cria uma espécie de workspace, onde é possível criar vários projetos e bibliotecas, e são essas bibliotecas internas que podemos exportar e podemos usar em outros projetos, e até publicar no NPM.

Com isso, muita coisa mudou, porque essa biblioteca interna, (pelo menos por enquanto, até a versão 7.1.2 do Angular), não contém os arquivos environments.prod.ts e environments.ts para tratarmos a diferença entre algumas configurações de produção e o ambiente de desenvolvimento, também não existe a estrutura da pasta assets para colocarmos nossas imagens e o Angular conseguir encontrá-las de forma fácil.

Essas dificuldades eu contornei da seguinte forma: as imagens eu coloco em texto base64 direto na tag <img> e quando preciso pegar uma URL em uma biblioteca uso JavaScript para obter a URL de forma dinâmica: (window.location.protocol + window.location.hostname;).

Outra mudança que houve foi o arquivo angular-cli.json que teve seu nome alterado para angular.json e sua estrutura mudou um pouco, passando a conter múltiplos projetos (como o de testes e as bibliotecas) pois como disse, o que criamos com “ng new” a partir da versão 7 do Angular se comporta como um workspace.

Agora que já falamos das mudanças e alguns contratempos que tive com elas, vamos a criação do projeto. Abrindo no terminal a pasta do seu workspace, digite:

$        ng new teste --create-application=false

          Quando indagado sobre a criação do Router e do CSS escolha as opções padrão.

A opção --create-aplication usada acima também é nova, e faz com que o Angular não crie o projeto inicial, bem com a pasta src, criando apenas o Workspace Angular por assim dizer. Basicamente isso é útil para criarmos bibliotecas, pois gera um workspace de mesmo nome da biblioteca. Note que o Angular aceita tanto comandos com camelCase quanto separados por ífem (-), então poderia ser --createApplication=false.

          Aproveite e dê uma olhada nos arquivos package.json que continua com as dependências do projeto  e angular.json, que está praticamente vazio aguardando a criação de um projeto ou biblioteca.

          Vamos criar a biblioteca, posicione o terminal na nova pasta criada (teste):

$        cd ..

E crie a biblioteca com o seguinte comando:

$        ng g library teste --prefix=lib

          Na linha acima, foi criada a biblioteca “teste” e ao invés de usarmos o prefixo “app” como de costume, dissemos para o Angular usar o prefixo “lib”. Fique à vontade para escolher o prefixo que desejar, isso é importante para evitar conflitos entre a biblioteca e os apps que a usam.
         
          Note que o conteúdo do arquivo angular.json mudou, temos nele a propriedade que indica a versão do projeto: “version”, a propriedade que indica o pacote raiz que contém os projetos: “newProjectRoot”, e então temos a propriedade que indica os nossos projetos: “projects”. Dentro da propriedade “projects” há uma propriedade para cada projeto que criarmos, nesse caso haverá apenas o projeto “teste”, e dentro da propriedade “teste” teremos as propriedades de configuração deste projeto específico, como o tipo do projeto, o prefixo usado, a raiz do projeto, o source do projeto e outras configurações pertinentes.

A estrutura do projeto também foi alterada, agora existe uma pasta “projects” com a pasta “teste” que é o nosso projeto dentro dela; e dentro da pasta “teste” temos o diretório “src” que conterá tudo que pertencer a lib propriamente dita, o arquivo “package.json” da lib que especificará suas dependências que serão compiladas e posteriormente instaladas junto com ela quando um cliente usar npm install e também o arquivo ng-package.json. Os demais arquivos são de menor importância. É também no arquivo “package.json” da lib que especificamos o autor, a licença, o repositório, etc.

       A lib já foi criada contendo um componente e um service dentro de src/lib . Também vemos outro arquivo importante dentro da pasta src: public_api.ts. Nesse arquivo devemos exportar todos os módulos, componentes e services que criarmos, para que possam ser usados por quem instalar nossa biblioteca.

          export * from './lib/teste.service';
export * from './lib/teste.component';
export * from './lib/teste.module';

No diretório principal, o arquivo “tsconfig.json” tem as configurações de transpilação e build do projeto. Ele recebe o path da biblioteca que criamos para podermos usar nesse projeto, enquanto que em projetos externos ela será instalada com npm install e o conteúdo ficará em node_modules.

"paths": {
      "teste": [
        "dist/teste"
      ],
      "teste/*": [
        "dist/teste/*"
      ]
}

          Vamos buildar o projeto:

$        ng build teste   

          Veja que o projeto é buildado normalmente. Mas a frente vamos ver como usá-lo em outro projeto e também como publicar no npm. Agora vamos ver como criar novos componentes para a biblioteca. Digite o comando abaixo:

$        ng g c meu-componente --project=teste

Veja que a única coisa que mudou foi que especificamos em qual projeto o componente seria gerado pelo AngularCli. O novo componente deve ser declarado no módulo da nossa biblioteca e também no arquivo de entrada, o public_api.ts.

Com isso podemos re-buildar nossa aplicação. Uma novidade desde a versão 6.2 é o re-build pode ser automático a medida que arquivos forem alterados, para isso basta acrescentar a opção --watch no momento do build, a partir de então os demais serão disparados sozinhos.

$        ng build teste --watch

Agora vamos ver como usar a biblioteca em um projeto externo e como publicar no npm.

Para isso temos que empacotar nossa biblioteca em uma arquivo .tgz, por tanto, vamos criar um script no “package.json” raiz para facilitar este trabalho. Na seção “scripts” adicione o seguinte trecho de código:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack"
 }

Agora podemos usar o seguinte comando para empacotar a biblioteca “teste”:

$        npm run npm_pack_teste

Isto criou o arquivo “teste-0.0.1.tgz” dentro de “dist/teste” com a versão especificada no arquivo “package.json” da lib como já dito anteriormente. Podemos inclusive criar um script que faz o build e o empacotamento de uma só vez:

"scripts": {
    ...
    "npm_pack_teste": "cd dist/teste && npm pack",
    "package_teste": "ng build teste && npm run npm_pack_teste "
 }

E agora basta executar:

$        npm run package_teste

Pronto, temos nossa biblioteca buildada e empacotada para usarmos onde quisermos! Para usarmos em projetos próprios não precisamos publicar no npm. Isso é bom para empresas que não querem expor suas bibliotecas, pode-se criar um repositório interno para elas e quando for usar o npm install basta passar o caminho completo de onde a biblioteca está.

Uma vez instalada a biblioteca, o uso é normal como qualquer pacote npm instalado na aplicação.

Agora vamos a publicação no npm. Antes de criar uma biblioteca, se é sua intenção publicá-la no npm é bom checar se o nome que pretende dar a sua biblioteca já não existe lá, para evitar ter que mudar depois de criado todo o projeto.

O arquivo “package.json” deve estar com as informações de nome, versão, autor, licença, repositório, palavras chaves e outras além das dependências, scripts, etc... como abaixo:

...
"name": "teste",
"version": "1.0.0",
"license": "MIT",
"author": {
    "name": "seu_nome",
    "email": "seu_email",
    "url": "seu_site_ou_blog"
 },
 "bugs": {
 "url":"url_issues_git"
  },
 "homepage":"url_git",
 "keywords": [
    "angular",
    "angular2",
    "angular4",
    "p-calendar",
    "p-calendar-ptbr",
    "primeNG",
    "datepicker",
    "calendar",
    "pt-BR"
 ],
 "repository": {
    "type": "git",
    "url": "git+https://endereço_rep_git"
 },
...

O npm usará sua página de README.md com a página inicial da sua biblioteca no servidor. Como agora estamos tratando de mais de uma biblioteca por workspace, o README.md deve ser copiado para o destino onde a biblioteca é buildada. Caso haja um arquivo LICENSE também deve ser colocado lá.

É preciso criar uma conta caso você não tenha, ou fazer login para poder compartilhar seus pacotes. A criação da conta é bem simples e eles pedem um username, password e e-mail. É necessário a confirmação do e-mail antes de publicar algo caso a conta seja nova. O comando para criar uma conta é:

$       npm adduser

Ao criar a conta ele já loga no NPM. Para efetuar logins posteriores, os mesmos dados são pedidos, e o comando é:

$       npm login

Agora podemos publicar nossa biblioteca, digitando o comando npm publish e passando o caminho do arquivo .tgz gerado:

$        npm publish .\dist\teste\teste-0.0.1.tgz

Bom, o artigo ficou um pouco grande porque expliquei algumas coisas com detalhes, mas espero ter ajudado! Abraços!




Links de referência:









sábado, 1 de dezembro de 2018

Resumo sobre Angular 4+

Como estamos sempre lidando com muitas tecnologias diferentes, cada uma delas cheia de particularidades, as vezes faço um resumo para não perder muito tempo procurando o básico. Esse é meu resumo pessoal sobre o Angular 4.

NPM

- npm install nome_da_biblioteca --save
- npm uninstall nome_da_biblioteca --save

Angular-Cli

- ng new nome_do_projeto => cria um projeto,  inclusive a pasta raiz.
- ng init => quando já existir a pasta raiz e quiser criar a estrutura do projeto (deve ser executado no diretório).
- ng serve => executa o projeto.
- ng g c nome-do-componente => cria o componente.
- ng g d nome-da-diretiva => cria uma diretiva.
- ng g s nome-do-servico => cria o serviço.
- ng g m nome-do-model => cria o módulo.
- ng g m nome-do-model --routing => cria o módulo e o módulo de rotas
- ng g g nome-do-guarda => cria um guarda de rotas
- ng g p nome-do-pipe => cria o pipe.
- ng lint => lista erros de javascript e anti-padrões do style guide do Angular

Componentes

- interpolação => {{variavel}}
- propert-binding => [propriedade]="variavel" => <input [value]="nome" />
- event-binding => (evento)="método" => (click)="salvar($event.target.value)"
- two-way-data-binding => [(ngModel)]="nome"

- comunicação do componente pai para o filho:

@Input() variavel: tipo;

- comunicação do componente filho para o pai:

@Output variavel_evento = new EventEmitter();

//em algum momento dentro de um método usa-se:
this.variavel_evento.emit(objeto_ou_valor);

Variável de referência

usa-se o '#' antes de um nome => #imputName => <input type="text" class="form-control" #imputName />

-então essa variável fica disponível em todo o template(componente.html), mas não no componente(componente.ts).

Para ser acessada no componente, tem duas formas:

-pode ser acessada através do decorator @ViewChild('nome_da_variavel')

@ViewChild('imputName') campo: ElementRef;
//para usar depois basta fazer:
//this.campo.nativeElement.value;

-pode ser passada para o componente através de um event:

<button type="button" class="btn btn-primary"
        (click)="adicionar(imputName.value)">Adicionar</button>
// valor será recebido no método adicionar(valor) do componente.ts.

Ciclo de vida:

- construtor
- ngOnChanges => disparado sempre quando o valor do property-binding é atualizado.
- ngOnInit => Quando o componente é inicializado.
- ngDoCheck => A cada ciclo de verificação de mudanças.
- ngAfterContentInit => depois de inserir conteúdo externo na view
- ngAfterContentChecked => a cada verificação de conteúdo inserido
- ngAfterViewInit => depois que o angular inicializa os componentes views e views filhas.
- ngAfterViewChecked => após a checagem dos componentes views e views filhas.
- ngOnDestroy => antes da destruição do componente.

Diretivas

- diretivas de componentes => diretivas dos nossos componentes => <meu-componente></meu-componente>
- diretivas estruturais => vem precedida de * (asterísco) => *ngFor, *ngIf, *ngSwitch, etc.
- diretivas de atributos => interagem com o elemento que foram aplicadas => ngStyle, ngClass, etc.

Ouvindo eventos do hopedeiro da diretiva e acessando atributos HTML:
-  Exemplo de como ouvir eventos:

  @HostListener('mouseover') onMouseOver(){
    this.renderer.setStyle(this.elementRef.nativeElement, 'background-color', 'blue');
  }

  @HostListener('mouseout') onMouseOut(){
    this.renderer.setStyle(this.elementRef.nativeElement, 'background-color', 'red');
  }

  constructor(private elementRef: ElementRef, private renderer: Renderer2 ) {

  }

- Exemplo de como acessar atributos:

@HostBinding('style.backgroundColor') backgroundColor: string;

Dessa forma, o @HostEvent não precisaria usar o rendered2 nem o elementRef e ficaria assim:

@HostListener('mouseover') onMouseOver(){
    this.backgroundColor = 'blue';
}

Pode-se usar o @input() para receber valores de quem for usar o componente com a diretiva criada.

Exportar a diretiva:
- As diretivas podem ser exportadas e terem seus métodos expostos da seguinte forma:

@Directive({
  selector: '[nome_do_seletor_da_diretiva]',
  exportAs: 'nome_da_diretiva'
})

- Isso possibilita que sejam usados de outras formas, veja como pegar a diretiva e usar seus métodos:

<input type="text" class="form-control" [(ngModel)]="nome"
        (focus)="adicionado = false" nome_do_seletor_da_diretiva
        #campo="nome_da_diretiva">

<button class="btn btn-info" (click)="campo.metodo_da_diretiva()">Clique-me</button>


NG-CONTENT
- Permite passar conteúdo (incluindo outros componentes) para um componente. Observe o uso do seletor e da classe para que isso funcione.
- Se eu tiver um componente chamado exemplo-ng-content.component.html com o seguinte conteúdo:

<div class="panel panel-default">
  <div class="panel-heading">
    <ng-content select=".titulo"></ng-content>
  </div>
  <div class="panel-body">
    <ng-content select=".corpo"></ng-content>
  </div>
</div>

pode ser usado em outro componente desta forma:

<app-exemplo-ng-content>
    <div class="titulo">Título do Painel</div>
    <div class="corpo">
        Conteúdo passado para o componente corpo.
    </div>
    <div class="corpo">
        Conteúdo 2 passado para o componente corpo.
    </div>
</app-exemplo-ng-content>

Form validations

- autocomplete="off" => desabilita autocomplite no formulário
- diretivas do angular:

required, email, minlength="5", maxlength="15", pattern="[a-zA-Z ]*"

- pegar o formulario:

<form #meuForm="ngForm">

- pegar campos do formulário:

<input type="text" #nome="ngModel" name="nome" [(ngModel)]="cliente.nome" />

- validar:

nome.haserror('required') => pode ser usado em um ngIf por exemplo e exibir ou não uma mensagem.

- propriedades interessantes:

nome_do_campo.touched => se o campo foi tocado
nome_do_campo.pristine => se o campo já teve algum valor ou está virgem
nome_do_campo.dirty => se o campo já foi alterado

- estilizando componentes invalidos dos forms com as classes do angular:

input.ng-invalid.ng-touched, select.ng-invalid.ng-touched {
  border: 1px solid red;
}

- binding de class:

<input type="text" #nome="ngModel" name="nome" [(ngModel)]="cliente.nome" [class.nome_da_classe]="propriedade_ou_condicao_boolean"/>

- binding de style:

<input type="text" #nome="ngModel" name="nome" [(ngModel)]="cliente.nome" [style.nome_da_propriedade]="propriedade_ou_condicao_boolean ? 'valor_1' : 'valor_2' "/>

- resetar um formulario:

<form autocomplete="off" #usuarioForm="ngForm"
      (ngSubmit)="salvar(usuarioForm)">

No submit do form estamos chamando o método salvar e passando o próprio form.
Então no componente basta resetarmos o form:

salvar(form: NgForm) {
//faz outras coisas
...
//reseta o formulário
    form.reset();
  }

Serviços

- A anotação @Injectable() permite que o serviço receba injeção de outros serviços.
- Serviços servem para comunicação com servidor.
- Para evitar duplicação de código.
- Lógica da aplicação deve estar nos serviços.
- Classes utilitárias devem ser feitas como serviços.
- Serviços são singletons se forem adicionados dentro de qualquer módulo na propriedade "providers: []" do decorator @NgModule. O que permite compartilhar recursos entre componentes naturalmente (listas, variáveis, etc).
- Caso sejam adicionados na propriedade "providers: []" do componente, serão uma instância para cada componente e componentes filhos, o que já impede esse compartilhamento global.
- Uma vez criadas instâncias separadas por componentes, a comunicação entre eles só pode ser feita através do EventEmitter e se o EventEmitter for uma propriedade estática.

static variavel_evento = new EventEmitter();

//dentro de algum método
this.variavel_evento.emit( objeto_ou_valor );

- Quem for escutar o evento deve fazer da seguinte forma:

// no contrutor recebe o serviço
constructor(private cursosService: CursosService) {}

// no ngOnInit se inscreve como ouvinte
CursosService.criouNovoCurso.subscribe(
      //faz alguma coisa aqui
curso => this.cursos.push(curso)
    );

 - Os services são declarados no provider dos módulos ou componentes como já descrito acima,
da forma abreviada ou extensa.

Abreviada:

@NgModule({
  declarations: [
    AppComponent,
    FuncionarioCardComponent,
    FuncionarioFormComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    FuncionarioService
  ],
  bootstrap: [AppComponent]
})

Extensa

@NgModule({
  declarations: [
    AppComponent,
    FuncionarioCardComponent,
    FuncionarioFormComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    { provide: FuncionarioService, useClass: FuncionarioService, }
  ],
  bootstrap: [AppComponent]
})

Na forma extensa, é possível fornecer um método Factory ao invés de uma classe.
A vantagem é que a factory pode instanciar uma classe com parâmetros se for necessário.

const criarFuncionarioService = () => {
  return new FuncionarioAbreviadoService(param1, param2...);
}

@NgModule({
  declarations: [
    AppComponent,
    FuncionarioCardComponent,
    FuncionarioFormComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    { provide: FuncionarioService, useFactory: criarFuncionarioService }
  ],
  bootstrap: [AppComponent]
})

Rotas

- Cria-se uma constante em um arquivo app.routing.ts ou no app.module.ts que seja
do tipo Routes do pacote "@angular/router". Esse  paths e componentes.
- O Routes é um array de paths e componentes e deve ser preenchido como no
exemplo abaixo:

const  APP_ROUTES: Routes = [
  { path: 'lancamentos', component: LancamentosPesquisaComponent },
  { path: 'lancamentos/novo', component: LancamentosCadastroComponent },
  { path: 'pessoas', component: PessoasPesquisaComponent },
  { path: 'pessoas/novo', component: PessoasCadastroComponent }
]

- Essa constante deve passar para uma constante do tipo ModuleWithProviders do pacote "@angular/core".
- Para isso é preciso usar o RouterModule do "@angular/router". Se essa constante foi criada em um arquivo
separado, ela deve ser exportada. O código fica assim:

export const routing: ModuleWithProviders = RouterModule.forRoot(APP_ROUTES);

- Para usar as rotas coloca-se a diretiva routerLink nos links recebendo o devido path declarado na constante
que no exemplo chamei de APP_ROUTES.

<li class="navbar-menuitem"><a routerLink="lancamentos">Lançamentos</a></li>

- Para as rotas funcionarem, em cada módulo é necessário importar o RouterModule do '@angular/router'.

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    BrowserModule,
    RouterModule
  ],
  providers: [
    ...
  ],
  bootstrap: [AppComponent]
})

- Para destacar rotas ativas, basta usar a diretiva routerLinkActive passando o nome da classe CSS que contém o estilo desejado.

<li class="navbar-menuitem" routerLinkActive="ativo"><a routerLink="lancamentos">Lançamentos</a></li>

- Para carregar rotas de forma lazying, dependendo da versão, pode-se usar uma dessas formas:

{ path: 'cursos', loadChildren: 'app/cursos/cursos.module#CursosModule'}  versão 2+

{ path: 'cursos', loadChildren: './cursos/cursos.module#CursosModule'}  versão 7+

{ path: 'cursos', loadChildren: () => import('./cursos/cursos.module').then(m => m.CursosModule)} versão 9+

Events

(focus)="myMethod()"  // An element has received focus
(blur)="myMethod()"   // An element has lost focus

(submit)="myMethod()"  // A submit button has been pressed

(change)="myMethod()"

(scroll)="myMethod()"

(cut)="myMethod()"
(copy)="myMethod()"
(paste)="myMethod()"

(keydown)="myMethod()"
(keypress)="myMethod()"
(keyup)="myMethod()"

(mouseenter)="myMethod()"
(mousedown)="myMethod()"
(mouseup)="myMethod()"

(click)="myMethod()"
(dblclick)="myMethod()"

(drag)="myMethod()"
(dragover)="myMethod()"
(drop)="myMethod()"