Angular, modal komponent, dostęp do różnych serwisów z poziomu modala.

0

Witam,

Chcę trochę zoptymalizować aplikację pisaną w angular. Do rzeczy, mam w aplikacji komponent do zbierania i walidacji danych wprowadzanych przez użytkownika, komponent ten jest wyświetlany w modalu. Bezpośrednio w komponencie sięgam do service, który komunikuje się z api i przetwarza dane. Działa to bez problemu w ramach jednego modułu.

Mam potrzebę użycia takiej samej funkcjonalności w dwóch kolejnych modułach, i tu dobrym rozwiązaniem było by wyciągnąć ten komponent do modułu share i używać go jako komponent re-używalny. Ale jak do dynamicznie tworzonego komponentu przekazać konkretny service, który będzie się komunikował z właściwym url dla danego modułu ? Ewentualnie jak z takiego komponentu w modalu odwołać się do metod w komponencie wywołującym modal ?

0

Wrzucenie w providers w Module obiektu gdzie sobie odpowiednią klasę / instancję wrzucisz w useClass / useValue nie zadziała? Jeżeli to nie zadziała, to możesz spróbować zaimportować sobie to w sposób jak importujesz np. Router ( https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L121 ).

0

Nie do końca, w zależności z którego modułu będzie komponent wywoływany będzie miał musiał mieć dostęp do serwisu / metod tego modułu, nie będzie to zawsze stały serwis / stała metoda.

0

Osobiście lubię jak wszystkie zależności są przekazywane wprost do komponentu w Input. Jest to najbardziej czytelne IMO. Ale popularne jest użycie @Inject i wtedy w każdym module możesz zapewnić inną wstrzykiwaną zależność w liście providers. Natomiast jeśli dynamicznie tworzysz komponent no to tutaj już nie DI angularowe wchodzi w rachubę a prostu przekazanie referencji ręczne do odpowiedniego serwisu. Także musiałbyś pokazać jakiś przykład konkretniejszy :).

0
Schadoow napisał(a):Natomiast jeśli dynamicznie tworzysz komponent no to tutaj już nie DI angularowe wchodzi w rachubę a prostu przekazanie referencji ręczne do odpowiedniego serwisu.

Nie wiem czy to najlepszy sposób, ale zrobiłem tak

wywołanie modal

    this.dialog.open(ScannerDataComponent, {
      data: {
        partNumber = this.partNumber ,
        fn: (data) => { return this.service.SaveData(data) },
      },
    })
    .afterClosed()
    .subscribe(()=>this.show = true)

Wywołanie fn() w komponencie > ScannerDataComponent wyświetlanym w modalu

      this.data.fn(data).subscribe(
        (m) => {
          this.display = m.code;
          this.result = true
        },
        (e) => {
          this.display = 'Error !!!'
          this.result = false
        },
      )

I w zależności od result przez [ngClass] przypisuję w divie wyświetlającym wynik odpowiednia klasę.
Taki komponent mogę użyć w dowolnym miejscu, a samą funkcję zapisującą dane przekazuję dopiero na etapie wywoływania komponentu.

Nie wiem czy to właściwe podejście ale wynik działania zgodny z oczekiwaniami.

0

@marcin82w: tak mniej więcej o to mi chodziło tylko teraz przez przypadek nie popierdziel się co gdzie ma jaki zasięg bo inny będzie mieć lambda a inny jak wydzielisz to do funkcji. Jak będziesz przekazywał funkcje i chciał się odwoływać do elementów z parent to pamiętaj o https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Function/bind w tym wypadku fn: mojaFunkcja.bind(this).

0

A i jeszcze jedna rzecz jak tworzysz sobie taki generyczny komponent to warto zabezpieczyć się przed hotStreamami bo o ile w tym przypadku domyslam się, że pod this.service.SaveData(data) jest cold bo jest tam po prostu call http o tyle jak np podasz tam ty albo ktos z zespołu hota to będziesz miał wycieki o tu this.data.fn(data).subscribe(. Także najprościej możesz użyć this.data.fn(data).pipe(first()).subscribe( albo z użyciem https://github.com/ngneat/until-destroy this.data.fn(data).pipe(untilDestroyed(this)).subscribe(

0

Właśnie próbowałem przekazać referencję do funkcji i wywołać ją w komponencie co poskutkowało błędami, zamiast tworzyć funkcję opakowującą wywołanie

this.service.SaveData(data) 

użyłem nowszego zapisu funkcji strzałkowej.

fn: (data) => { return this.service.SaveData(data) },

Efekt taki sam a mniej pisania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1