Açısal 8 ve 9'da 'Pencere' ile Pencere'yi sağlama ve enjekte etme arasındaki fark nedir?


10

Bu sürümleri kullanan iki Açısal projem var:

  • 9.0.0-next.6
  • 8.1.0

Sürüm 9'da bunu sağlamak ve enjekte etmek için windowkullandım:

@NgModule({
  providers: [
    {
      provide: Window,
      useValue: window
    },
  ]
})

export class TestComponent implements OnInit {
  constructor(@Inject(Window) private window: Window)
}

Hangi iyi çalışıyor.


Sürüm 8'e bu yaklaşımı kullanmak derleme sırasında uyarılar ve hatalar verdi:

Uyarı: TestComponent için tüm parametreler çözülemiyor…

Ben böyle tek tırnak kullanarak çözdüm:

@NgModule({
  providers: [
    {
      provide: 'Window',
      useValue: window
    },
  ]
})

export class TestComponent implements OnInit {
  constructor(@Inject('Window') private window: Window)
}

Her iki sürüm arasındaki fark nedir?
Açısal 8 ve 9'da bu şeye neden olan fark nedir?


Ben ve diğer öğrenmek ve daha iyi anlamak hangi bir cevap alabilirsiniz lütuf ile umut sağlayıcıları ve di açısal ve çerçeve çalışmalarının farklı versiyonları.
abajur

Yanıtlar:


6

Uygulamanızın Sunucu Tarafı Oluşturma ile çalışabilmesi için yalnızca pencere üzerinden jeton kullanmanızı değil, aynı zamanda referans vermeden bu simgeyi SSR dostu bir şekilde oluşturmanızı öneririz window. Angular, DOCUMENTerişim için yerleşik jetona sahiptir document. Projelerimin windowjetonlarla kullanması için bulduğum şey :

import {DOCUMENT} from '@angular/common';
import {inject, InjectionToken} from '@angular/core';

export const WINDOW = new InjectionToken<Window>(
    'An abstraction over global window object',
    {
        factory: () => {
            const {defaultView} = inject(DOCUMENT);

            if (!defaultView) {
                throw new Error('Window is not available');
            }

            return defaultView;
        },
    },
);

Cevabınız için çok teşekkür ederim. Çok faydalı ve gelecekte böyle bir çözüm kullanacağım.
abajur

5

ValueProviderArabirim dikkate alındığında :

export declare interface ValueProvider extends ValueSansProvider {
    /**
     * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.
     */
    provide: any;
    /**
     * When true, injector returns an array of instances. This is useful to allow multiple
     * providers spread across many files to provide configuration information to a common token.
     */
    multi?: boolean;
}

provideMülkiyet türüdür any. Bu, herhangi bir nesnenin ( Windowkurucu dahil ) içine girebileceği anlamına gelir . Nesne aslında önemli değil, sadece referans , yapıcıya bir parametre enjekte etmek için hangi sağlayıcının kullanılması gerektiğini belirlemek için önemlidir.

Doğal Windowyapıcıyı bir enjeksiyon jetonu olarak kullanmak iyi bir uygulama olarak düşünülmemelidir . Çünkü derleme zamanında başarısız Windowbir tarayıcı ortamında çalışma zamanında var, o da daktilo olarak var declareama Açısal 8 derleyici ilişkilendirmek için statik kod analizi yapamaz Windowsağlayıcıların ve Windowatama beri, bir şantiye parametrelerinde Windowyapılır tarayıcı tarafından, kod tarafından değil. Yine de Açısal 9'da neden çalıştığından emin değilim ...

Bağımlılık sağlayıcıyı temsil eden kendi enjeksiyon simgenizi oluşturmalısınız. Bu enjeksiyon jetonu şunlardan biri olmalıdır:

  • Özel bir dize (yaptığınız gibi 'Window')
  • Adanmış InjectionToken. Örneğinexport const window = new InjectionToken<Window>('window');

Dahası, Açısal kod platform agnostik olmalıdır (bir tarayıcıda ve bir Node.js sunucusunda da yürütülebilir olmalıdır), bu nedenle dönen windowveya undefined/null bileşenlerde undefined/ nullkasasını daha sonra .


1
Ayrıntılı cevabınız için çok teşekkür ederim. Çok yardımcı oldu.
abajur

1
Çok iyi! Teşekkürler. Açısal belgeleri (v8 ve v9) kontrol ettim ve dizeleri kullandıkları tek bir örnek bulamadım. :( Bunu dokümanlarda gerçekten açıklamalılar!
Zaphoid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.