funkcja wywołania angular2 komponentu macierzystego

85

Mam aplikację, w której mam komponent do przesyłania, w którym mogę przesłać plik. Jest osadzony w body.component.

Podczas przesyłania powinien używać funkcji (np. BodyComponent.thefunction()) Komponentu nadrzędnego (wywołanie, aby zaktualizować dane): ale tylko wtedy, gdy nadrzędny jest konkretnie body.component. Przesyłanie może być również używane w innym miejscu z innym zachowaniem.

Coś jak parent(this).thefunction(), jak to zrobić?

PascalVKooten
źródło

Odpowiedzi:

149

Utworzyłbym zdarzenie niestandardowe w komponencie podrzędnym. Coś w tym stylu:

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

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

Twój komponent nadrzędny może zarejestrować się na to wydarzenie

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

  someMethod(event) {
  }
}

Innym sposobem byłoby wstrzyknięcie komponentu rodzicielskiego do komponentu dziecięcego, ale będą one ze sobą silnie połączone ...

Thierry Templier
źródło
Masz jakiś pomysł, dlaczego mam niezdefiniowany błąd wyjściowy? Jest zdefiniowany w maszynopisie u góry, importując z angular2/core. Dziennik konsoli pokazuje problem z angular2-polyfills
PascalVKooten
Och, w mojej odpowiedzi jest literówka: @Ouputzamiast @Output. To może być problem ... Zaktualizowałem odpowiedź.
Thierry Templier
Heh, nie zauważyłem. To było to.
PascalVKooten
Teraz otrzymuję uploadComplete is not definednotatkę, którą właśnie skopiowałem jako przykłady. Rodzic również ma "someMethod", ale już ma z nim problem uploadComplete. Komponent nadrzędny korzysta z (przesłanego) powiązania w węźle podrzędnym i ma już dziecko jako dyrektywę.
PascalVKooten
4
dyrektywy i potoki wewnątrz @Component są przestarzałe z kątowego RC6.
alex351
49

Poniżej pracuje dla mnie w najnowszym

Angular5

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

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

W ParentTemplateszablonie

<child-component (myEvent)="anyParentMehtod($event)"
Shabbir Dhangot
źródło
3
To dobre rozwiązanie, ponieważ jest proste, a rodzic decyduje, którą metodę wywołać. Ja lubię :-)
Jette
1
Co jeśli korzystam z gniazdka routera? Czy nadal mogę używać (myEvent)?
Robert Williams
Jest to składnik podrzędny używany wewnątrz komponentu rodzica. Nie wiem o gniazdku routera. Może to pytanie ci pomoże. stackoverflow.com/questions/45949476/…
Shabbir Dhangot
33

Rozwiązanie bez wydarzeń.

Załóżmy, że mam ChildComponentiz tego, że chcę wywołać metodę, do myMethod()której należy ParentComponent(zachowując oryginalny kontekst rodzica).

Klasa komponentu nadrzędnego:

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

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

    myMethod() {
         ...
    }
}

Szablon nadrzędny:

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

Szablon podrzędny

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

    @Input() myMethod: Function;

    // here I can use this.myMethod() and it will call ParentComponent's myMethod()
}
Francesco Borzi
źródło
1
Próbowałem tego użyć, ale to nie działa dla mnie. W mojej wersji myMethod odwołuje się do zestawu zakładek w komponencie nadrzędnym (próbuję przełączyć karty z elementu podrzędnego elementu nadrzędnego). Kiedy odnoszę się do tego w rodzicu, wszystko działa. Od dziecka dostaje się do myMethod, ale nie zmienia karty. Zastanawiam się więc, czy zestaw zakładek, do którego się odnosi, jest kopią prawdziwego, gdy dziecko uzyskuje do niego dostęp. Właściwie nie jestem pewien, co się tutaj dzieje, kiedy this.myMethod.bind(this)wraca. (Prawdopodobnie zamiast tego robię coś zasadniczo złego.)
Katharine Osborne,
Wiem, ale nie używam ósmej wersji. Potrzebuję tego dla Ionic 3, który używa wersji 5.
Vasilis Grecja
@VasilisGreece Nie jestem pewien, jak ci pomóc, ale zdecydowanie sugeruję aktualizację do najnowszej wersji Ionic (obecnie 4)
Francesco Borzi
Najprostszy i najbardziej bezpośredni sposób wywołania metody rodzica, unikając niepotrzebnego importu. Korzystanie z Angular 10 13.11.2020. Doceniony.
CPHPython
23

Możesz wstrzyknąć komponent nadrzędny do komponentu podrzędnego.

Aby uzyskać więcej informacji, zobacz
- Jak wstrzyknąć komponent nadrzędny do komponentu podrzędnego?
- Komponent potomny Angular 2 odnosi się do komponentu nadrzędnego W ten sposób możesz upewnić się, że thefunction()jest wywoływany tylko wtedy, gdy rodzic jest body.component.

constructor(@Host() bodyComp: BodyComponent) {

W przeciwnym razie @Output()preferowane jest używanie do komunikacji między dzieckiem a rodzicem.

Günter Zöchbauer
źródło
1
Przy okazji, musiałem zrobić constructor(@Host() bodyComp: BodyComponent)… może to ostatnio zostało zmienione. Działa świetnie, dzięki!
Eddy Verbruggen
Wielkie dzięki, coś pomieszałem - naprawiono
Günter Zöchbauer