¿Cómo devolver un valor de una función EventEmitter?


Tengo esta función en mi componente core:

 isValid(value: any) {

   // Do some stuff and return something based on the result

   return false;
 }

Que paso a la other-component así: {[12]]}

<other-component (onBeforeAdding)="isValid($event)"></other-component>

Y en other-component obtuve esta función EventEmitter que debería ejecutarse antes que otras cosas y devolver un valor que indica que un valor es válido o no:

 @Output() onBeforeAdding: EventEmitter<any> = new EventEmitter();

 let isValid = this.onBeforeAdding.emit(value) || true;

 if (isValid) {

   // Do stuff
 }

El problema aquí es que una función EventEmitter no puede devolver un valor ya que es asíncrona (aunque desde rc2 parece que esto es opcional pasando true a la función new EventEmitter? Incluso hacerlo no solucionará este problema obstante). Así que isValid siempre será true independientemente de lo que devuelva la función.

¿Cómo puedo devolver un valor de la función EventEmitter?

 27
Author: Chrillewoodz, 2016-06-29

4 answers

La respuesta corta es que no puedes hacer esto con @Output, pero puedes hacer algo muy similar con @Input.

Misma función en el componente core:

isValid(value: any): boolean {
  // Do some stuff and return something based on the result
  return false;
}

Pase la definición de la función a other-component como un @Input:

<other-component [onBeforeAddingProcessor]="isValid"></other-component>

En other-component:

@Input() onBeforeAddingProcessor: (value: any) => boolean;

ngOnInit() {
  // onBeforeAddingProcessor won't be defined in the constructor
  let isValid = this.onBeforeAddingProcessor(value);

  if (isValid) {
    // Do stuff
  }
}

Métodos de acceso this

Si tienes que acceder a this en la función que proporcionas, entonces es necesario pasar un método que ya tenga el enlace this-context:

isValid = (value: any) => {
  return this.myService.checkValue(value);
}

De lo contrario, llamadas angulares el método con this del componente, no el consumidor del componente. Pequeña sugerencia con respecto al rendimiento( aunque no probado): si este método es grande y el número de instancias del componente es alto, entonces debe factorizar las partes más grandes del código a una función miembro privada y llamar a esta función desde donde se factorizó. Motivo: Above no crea una función en el prototipo de la clase, sino que sella una copia de esta función para cada instancia del componente. Esto puede consume mucha memoria que se puede evitar fácilmente.

 41
Author: Isaac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-13 16:23:06

Necesita suscribirse al emisor de eventos para obtener el valor:

this.onBeforeAdding.emit(value || true);

this.onBeforeAdding.subscribe(isValid => {
  if (isValid) {
    // Do stuff
  }
});
 1
Author: Thierry Templier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-29 15:00:07

La función emit envía una señal broadcast a todos los oyentes pasando el valor que determinaste. Creo que la lógica isValid necesita emitir el evento, porque la responsabilidad de EventEmitter es emitir eventos y no validar cosas. ¿Cómo desea escribir exactamente este flujo isValid?

 0
Author: Reginaldo Camargo Ribeiro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-29 14:54:06

Te sugiero que construyas un pequeño ejemplo.

Pero así es como entiendo su pregunta.

Creo que debería usar otra propiedad con EventEmitter porque está tratando de obtener el retorno de isValid() del componente principal y EventEmitter es solo una calle de un solo sentido.

Así que crearía una variable observable y la asignaría a otro componente, para que pueda suscribirse a ella. Cuando isValid () se ejecuta, use next para publicar un nuevo valor.

Un ejemplo simple es como tú puede suscribirse a valueChanges desde un control de formulario.

La respuesta de@Isaac es usar @input pero si quieres usar observable para esto, mi solución encajará mejor.

 0
Author: maxisam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-13 15:21:43