AngularJS tiene los parámetros & donde puede pasar una devolución de llamada a una directiva (por ejemplo, la forma de devolución de llamada de AngularJS . ¿Es posible pasar una devolución de llamada como un @Input
componente angular (algo como a continuación)? Si no, ¿qué sería lo más parecido a qué? AngularJS hace?
@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
fuente
fuente
@Input
forma sugerida hizo que mi código sea un spagetti y no es fácil de mantener.@Output
Es una forma mucho más natural de hacer lo que quiero. Como resultado, cambié la respuesta aceptadaRespuestas:
Creo que es una mala solución. Si desea pasar una Función a un componente con
@Input()
,@Output()
decorador es lo que está buscando.fuente
@Output
yEventEmitter
. Entonces, aquí está la documentación angular para @Output para aquellos interesados.ACTUALIZAR
Esta respuesta se envió cuando Angular 2 todavía estaba en alfa y muchas de las características no estaban disponibles / indocumentadas. Si bien lo siguiente seguirá funcionando, este método ahora está completamente desactualizado. Recomiendo encarecidamente la respuesta aceptada a continuación.
Respuesta original
Sí, de hecho lo es, sin embargo, querrás asegurarte de que tenga un alcance correcto. Para esto, he usado una propiedad para asegurar que eso
this
significa lo que quiero.fuente
Parent -> Child
ngOnInit
me acaba de utilizar:this.theCallback = this.theCallback.bind(this)
y entonces puede pasar de largotheCallback
en lugar detheBoundCallback
.Una alternativa a la respuesta que SnareChops dio.
Puede usar .bind (this) en su plantilla para tener el mismo efecto. Puede que no sea tan limpio pero ahorra un par de líneas. Actualmente estoy en angular 2.4.0
fuente
@Input
está causando que el código se convierta en espagueti y el uso de@Output
resultados en un proceso más natural / desenredadoEn algunos casos, es posible que necesite que un componente principal realice la lógica de negocios. En el siguiente ejemplo, tenemos un componente secundario que representa la fila de la tabla dependiendo de la lógica proporcionada por el componente principal:
Entonces, quería demostrar 2 cosas aquí:
fuente
.bind(this)
[getRowColor]="getColor"
[getRowColor]="getColor()"
Como ejemplo, estoy usando una ventana modal de inicio de sesión, donde la ventana modal es la principal, el formulario de inicio de sesión es el secundario y el botón de inicio de sesión llama a la función de cierre de la principal modal.
El modal padre contiene la función para cerrar el modal. Este padre pasa la función de cierre al componente hijo de inicio de sesión.
Después de que el componente de inicio de sesión secundario envíe el formulario de inicio de sesión, cierra el modal principal mediante la función de devolución de llamada principal
fuente
Una alternativa a la respuesta que dio Max Fahl.
Puede definir la función de devolución de llamada como una función de flecha en el componente principal para que no necesite vincular eso.
fuente
Pasar método con argumento, usando .bind dentro de la plantilla
fuente
Usar patrón observable. Puede poner el valor Observable (no Asunto) en el parámetro de entrada y administrarlo desde el componente principal. No necesita la función de devolución de llamada.
Ver ejemplo: https://stackoverflow.com/a/49662611/4604351
fuente
Otra alternativa
El OP solicitó una forma de usar una devolución de llamada. En este caso, se refería específicamente a una función que procesa un evento (en su ejemplo: un evento de clic), que se tratará como la respuesta aceptada de @serginho sugiere: con
@Output
yEventEmitter
.Sin embargo, hay una diferencia entre una devolución de llamada y un evento: con una devolución de llamada, su componente hijo puede recuperar algunos comentarios o información del padre, pero un evento solo puede informar que algo sucedió sin esperar ningún comentario.
Hay casos de uso donde es necesaria una retroalimentación, ej. obtener un color o una lista de elementos que el componente necesita manejar. Puede usar funciones enlazadas como sugieren algunas respuestas, o puede usar interfaces (esa es siempre mi preferencia).
Ejemplo
Supongamos que tiene un componente genérico que opera sobre una lista de elementos {id, name} que desea usar con todas las tablas de la base de datos que tienen estos campos. Este componente debe:
Componente hijo
Usando el enlace normal necesitaríamos 1
@Input()
y 3@Output()
parámetros (pero sin ningún comentario del padre). Ex.<list-ctrl [items]="list" (itemClicked)="click($event)" (itemRemoved)="removeItem($event)" (loadNextPage)="load($event)" ...>
, pero al crear una interfaz solo necesitaremos una@Input()
:Componente principal
Ahora podemos usar el componente de lista en el padre.
Tenga en cuenta que
<list-ctrl>
recibethis
(componente principal) como el objeto de devolución de llamada. Una ventaja adicional es que no es necesario enviar la instancia principal, puede ser un servicio o cualquier objeto que implemente la interfaz si su caso de uso lo permite.El ejemplo completo está en este stackblitz .
fuente
La respuesta actual se puede simplificar a ...
fuente
.bind(this)
eso, elthis
interior de la devolución de llamada será lowindow
que puede no importar dependiendo de su caso de uso. Sin embargo, si tienethis
alguna devolución de llamada,.bind(this)
es necesario. Si no lo hace, esta versión simplificada es el camino a seguir.this
dentro de la función de devolución de llamada. Es solo propenso a errores.