O AngularJS possui os parâmetros & nos quais você pode passar um retorno de chamada para uma diretiva (por exemplo, maneira de retorno de chamada AngularJS . É possível passar um retorno de chamada como um @Input
componente angular (algo como abaixo)? AngularJS faz?
@Component({
selector: 'suggestion-menu',
providers: [SuggestService],
template: `
<div (mousedown)="suggestionWasClicked(suggestion)">
</div>`,
changeDetection: ChangeDetectionStrategy.Default
})
export class SuggestionMenuComponent {
@Input() callback: Function;
suggestionWasClicked(clickedEntry: SomeModel): void {
this.callback(clickedEntry, this.query);
}
}
<suggestion-menu callback="insertSuggestion">
</suggestion-menu>
angularjs
angular
typescript
Michail Michailidis
fonte
fonte
@Input
modo sugerido fez com que meu código fosse complicado e não fosse fácil de manter.@Output
s são uma maneira muito mais natural de fazer o que eu quero. Como resultado eu mudei a resposta aceitaRespostas:
Eu acho que é uma má solução. Se você deseja passar uma Função para o componente
@Input()
,@Output()
decorador é o que você está procurando.fonte
@Output
eEventEmitter
. Então, aqui está a documentação angular do @Output para os interessados.ATUALIZAR
Esta resposta foi enviada quando o Angular 2 ainda estava em alfa e muitos dos recursos estavam indisponíveis / não documentados. Embora o abaixo ainda funcione, este método agora está totalmente desatualizado. Eu recomendo fortemente a resposta aceita acima.
Resposta original
Sim, na verdade é, no entanto, você deve ter certeza de que o escopo está correto. Para isso, usei uma propriedade para garantir que isso
this
significa o que eu quero.fonte
Parent -> Child
ngOnInit
eu apenas usaria:this.theCallback = this.theCallback.bind(this)
e então você pode passar adiante emtheCallback
vez detheBoundCallback
.Uma alternativa para a resposta que SnareChops deu.
Você pode usar .bind (this) no seu modelo para ter o mesmo efeito. Pode não ser tão limpo, mas salva algumas linhas. Atualmente, estou no angular 2.4.0
fonte
@Input
está causando o código para se tornar espaguete e usando@Output
os resultados em um processo mais natural / desembaraçadosEm alguns casos, pode ser necessário que a lógica comercial seja executada por um componente pai. No exemplo abaixo, temos um componente filho que renderiza a linha da tabela, dependendo da lógica fornecida pelo componente pai:
Então, eu queria demonstrar duas coisas aqui:
fonte
.bind(this)
[getRowColor]="getColor"
e não[getRowColor]="getColor()"
;-)Como exemplo, estou usando uma janela modal de login, em que a janela modal é o pai, o formulário de login é o filho e o botão de login chama de volta para a função de fechamento do pai modal.
O modal pai contém a função para fechar o modal. Esse pai passa a função close para o componente filho de logon.
Depois que o componente de login filho envia o formulário de login, ele fecha o modal pai usando a função de retorno de chamada do pai
fonte
Uma alternativa à resposta que Max Fahl deu.
Você pode definir a função de retorno de chamada como uma função de seta no componente pai para não precisar vinculá-lo.
fonte
Passando método com argumento, usando .bind dentro do modelo
fonte
Use padrão observável. Você pode colocar o valor observável (não o assunto) no parâmetro Input e gerenciá-lo a partir do componente pai. Você não precisa da função de retorno de chamada.
Veja o exemplo: https://stackoverflow.com/a/49662611/4604351
fonte
Outra alternativa.
O OP pediu uma maneira de usar um retorno de chamada. Nesse caso, ele estava se referindo especificamente a uma função que processa um evento (em seu exemplo: um evento de clique), que deve ser tratado como a resposta aceita por @serginho sugere: with
@Output
eEventEmitter
.No entanto, há uma diferença entre um retorno de chamada e um evento: Com um retorno de chamada, o componente filho pode recuperar alguns comentários ou informações dos pais, mas um evento pode apenas informar que algo aconteceu sem esperar nenhum retorno.
Existem casos de uso em que um feedback é necessário, por exemplo. obtenha uma cor ou uma lista de elementos que o componente precisa manipular. Você pode usar funções vinculadas, como algumas respostas sugeriram, ou pode usar interfaces (essa é sempre a minha preferência).
Exemplo
Vamos supor que você tenha um componente genérico que opera sobre uma lista de elementos {id, nome} que você deseja usar com todas as suas tabelas de banco de dados que possuem esses campos. Este componente deve:
Componente filho
Usando a ligação normal, precisaríamos de 1
@Input()
e 3@Output()
parâmetros (mas sem nenhum feedback do pai). Ex.<list-ctrl [items]="list" (itemClicked)="click($event)" (itemRemoved)="removeItem($event)" (loadNextPage)="load($event)" ...>
, mas, ao criar uma interface, precisaremos de apenas uma@Input()
:Componente pai
Agora podemos usar o componente list no pai.
Observe que o
<list-ctrl>
recebimentothis
(componente pai) é o objeto de retorno de chamada. Uma vantagem adicional é que não é necessário enviar a instância pai, ela pode ser um serviço ou qualquer objeto que implemente a interface, se o seu caso de uso permitir.O exemplo completo está neste stackblitz .
fonte
A resposta atual pode ser simplificada para ...
fonte
.bind(this)
isso, othis
interior do retorno de chamada será owindow
que pode não interessar, dependendo do seu caso de uso. No entanto, se você tiverthis
o retorno de chamada,.bind(this)
é necessário. Caso contrário, esta versão simplificada é o caminho a seguir.this
dentro da função de retorno de chamada. É apenas propenso a erros.