función de llamada angular2 del componente principal

83

Tengo una aplicación donde tengo un componente de carga donde puedo cargar un archivo. Está incrustado en el body.component.

En la carga, debe usar una función (por ejemplo BodyComponent.thefunction()) del componente principal (hacer una llamada para actualizar los datos): pero solo si el padre es específicamente el body.component. La carga también puede usarse en otros lugares con un comportamiento diferente.

Algo como parent(this).thefunction(), ¿cómo hacer eso?

PascalVKooten
fuente

Respuestas:

145

Crearía un evento personalizado en el componente secundario. Algo como eso:

@Component({
  selector: 'child-comp',
  (...)
})
export class ChildComponent {
  @Output()
  uploaded = new EventEmitter<string>();

  uploadComplete() {
    this.uploaded.emit('complete');
  }

Su componente principal podría registrarse en este evento

@Component({
  template `
    <child-comp (uploaded)="someMethod($event)"></child-comp>
  `,
  directives: [ ChildComponent ]
})
export class ParentComponent {
  (...)

  someMethod(event) {
  }
}

Otra forma sería inyectar el componente principal en el secundario, pero estarán fuertemente vinculados entre sí ...

Thierry Templier
fuente
¿Alguna idea de por qué tengo un error de salida indefinido? Se define en texto mecanografiado en la parte superior mediante la importación de angular2/core. El registro de la consola muestra un problema con angular2-polyfills
PascalVKooten
Oh, hay un error tipográfico en mi respuesta: en @Ouputlugar de @Output. Podría ser el problema ... Actualicé mi respuesta.
Thierry Templier
Je, no me di cuenta. Eso fue todo.
PascalVKooten
Ahora obtengo una uploadComplete is not definednota de que los copié como ejemplos. El padre también tiene "someMethod", pero ya tiene un problema con uploadComplete. El componente principal usa el enlace (cargado) en el nodo secundario, y ya tenía el elemento secundario como directiva.
PascalVKooten
4
directivas y tuberías dentro de @Component están en desuso de angular RC6.
alex351
47

A continuación se trabajó para mí en la última

Angular5

class ChildComponent {
  @Output() myEvent = new EventEmitter<string>();

  callParent() {
    this.myEvent.emit('eventDesc');
  }
}

En ParentTemplatela plantilla

<child-component (myEvent)="anyParentMehtod($event)"
Shabbir Dhangot
fuente
3
Ésta es una buena solución, porque es simple y el padre decide a qué método llamar. Me gusta :-)
Jette
1
¿Qué pasa si estoy usando un router-outlet? ¿Puedo seguir usando (myEvent)?
Robert Williams
Es para el componente secundario utilizado dentro del componente principal. No estoy seguro de la salida del enrutador. Quizás esta pregunta te ayude. stackoverflow.com/questions/45949476/…
Shabbir Dhangot
31

Solución sin eventos de por medio.

Supongamos que tengo un ChildComponenty de ahí quiero llamar al método al myMethod()que pertenece ParentComponent(manteniendo el contexto del padre original).

Clase de componente principal:

@Component({ ... })
export class ParentComponent {

    get myMethodFunc() {
        return this.myMethod.bind(this);
    }

    myMethod() {
         ...
    }
}

Plantilla principal:

<app-child [myMethod]="myMethodFunc"></app-child>

Plantilla infantil

@Component({ ... })
export class ChildComponent {

    @Input() myMethod: Function;

    // here I can use this.myMethod() and it will call ParentComponent's myMethod()
}
Francesco Borzi
fuente
1
Intenté usar esto pero no me funciona. En mi versión de myMethod, hace referencia a un conjunto de pestañas en el componente principal (estoy tratando de cambiar las pestañas de un hijo del padre). Cuando hago referencia a esto en el padre, todo funciona. Desde el niño está entrando en myMethod, pero no cambiando la pestaña. Así que me pregunto si el conjunto de pestañas al que hace referencia es una copia del real cuando el niño accede a él. En realidad, no estoy seguro de lo que sucede aquí cuando this.myMethod.bind(this)se devuelve. (Posiblemente, en cambio, estoy haciendo algo fundamentalmente mal.)
Katharine Osborne
Lo sé, pero no estoy usando la octava versión. Necesito esto para Ionic 3 que usa la versión 5.
Vasilis Grecia
@VasilisGreece No estoy seguro de cómo ayudarlo, pero le sugiero que actualice a la última versión Ionic (actualmente 4)
Francesco Borzi
La forma más sencilla y directa de llamar al método principal evitando importaciones innecesarias. Usando Angular 10 el 2020-11-13. Apreciado.
CPHPython hace
23

Puede inyectar el componente principal al componente secundario.

Para obtener más detalles, consulte
- ¿Cómo inyecto un componente principal en un componente secundario?
- El componente secundario de Angular 2 se refiere al componente principal. De esta manera, puede asegurarse de que thefunction()solo se llame cuando el elemento principal sea body.component.

constructor(@Host() bodyComp: BodyComponent) {

De lo contrario, @Output()se prefiere usar para comunicarse de un niño a otro.

Günter Zöchbauer
fuente
1
Por cierto, tenía que hacerlo constructor(@Host() bodyComp: BodyComponent)... tal vez se cambió recientemente. ¡Funciona muy bien, gracias!
Eddy Verbruggen
Muchas gracias, mezclé algo - arreglado
Günter Zöchbauer