Mam dwa projekty Angular wykorzystujące te wersje:
- 9.0.0-next.6
- 8.1.0
W wersji 9 użyłem tego, aby dostarczyć i wstrzyknąć window
obiekt:
@NgModule({
providers: [
{
provide: Window,
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject(Window) private window: Window)
}
Które działa dobrze.
Takie podejście do wersji 8 generowało ostrzeżenia i błędy podczas kompilacji:
Ostrzeżenie: nie można rozwiązać wszystkich parametrów TestComponent…
Rozwiązałem to za pomocą pojedynczych cudzysłowów, takich jak to:
@NgModule({
providers: [
{
provide: 'Window',
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject('Window') private window: Window)
}
Jaka jest różnica między obiema wersjami?
Jaka jest różnica w Angular 8 i 9, która powoduje to?
Odpowiedzi:
Aby Twoja aplikacja działała z renderowaniem po stronie serwera, sugeruję nie tylko używanie okna przez token, ale także tworzenie tego tokena w sposób przyjazny dla SSR, bez odwoływania się
window
w ogóle. Angular ma wbudowanyDOCUMENT
token dostępudocument
. Oto, co wymyśliłem, aby moje projekty mogły używaćwindow
za pomocą tokenów:źródło
Biorąc pod uwagę
ValueProvider
interfejs:provide
Nieruchomość jest typuany
. Oznacza to, że dowolny obiekt (włącznie zWindow
konstruktorem) może wejść do niego. Obiekt w rzeczywistości nie ma znaczenia, tylko odniesienia mają znaczenie w celu ustalenia, który dostawca powinien zostać użyty do wstrzyknięcia parametru do konstruktora.Nie należy uważać za dobrą praktykę używania natywnego
Window
konstruktora jako tokena wstrzykiwania. Nie powiedzie się w czasie kompilacji, ponieważWindow
istnieje w czasie wykonywania w środowisku przeglądarki, istnieje również jako TypeScript,declare
ale kompilator Angular 8 nie może przeprowadzić analizy kodu statycznego w celu skorelowaniaWindow
parametrów dostawców iWindow
konstruktora, ponieważ przypisanieWindow
jest wykonane przez przeglądarkę, a nie przez kod. Nie jestem pewien, dlaczego działa w Angular 9, chociaż ...Należy utworzyć własny token wstrzykiwania, który reprezentuje dostawcę zależności. Ten token wtrysku powinien być:
'Window'
)InjectionToken
. Na przykładexport const window = new InjectionToken<Window>('window');
Ponadto kod Angular powinien być niezależny od platformy (powinien być wykonywalny w przeglądarce i na serwerze Node.js), więc lepiej byłoby użyć fabryki, która zwraca
window
lubundefined
/null
, a następnie obsługiwaćundefined
/null
case w komponentach.źródło