私は2つのAngularこれらのバージョンを使用するプロジェクトを持っています:
バージョン9では、これを使用してwindow
オブジェクトを提供および注入しました。
@NgModule({
providers: [
{
provide: Window,
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject(Window) private window: Window)
}
それはうまくいきます。
このアプローチをバージョン8に適用すると、コンパイル中に警告とエラーがスローされました。
警告:TestComponentのすべてのパラメーターを解決できません…
私はこのように単一引用符を使用してそれを解決しました:
@NgModule({
providers: [
{
provide: 'Window',
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject('Window') private window: Window)
}
両方のバージョンの違いは何ですか?
これを引き起こすAngular 8と9の違いは何ですか?
アプリがサーバー側レンダリングで機能するためには、ウィンドウスルートークンを使用するだけでなく、window
をまったく参照せずに、SSRフレンドリーな方法でこのトークンを作成することをお勧めします。 Angularには、DOCUMENT
にアクセスするためのdocument
トークンが組み込まれています。ここで、プロジェクトがトークンを通じてwindow
を使用するために思いついたものを示します。
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;
},
},
);
ValueProvider
インターフェースを検討する:
_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;
}
_
provide
プロパティのタイプはany
です。つまり、任意のオブジェクト(Window
コンストラクターを含む)がその中に入ることができます。オブジェクトは実際には関係ありません。コンストラクタにパラメータを挿入するためにどのプロバイダを使用する必要があるかを特定するには、参照のみが関係します。
ネイティブのWindow
コンストラクターを注入トークンとして使用することは、良い習慣とは見なされません。 Window
はブラウザー環境で実行時に存在し、TypeScript declare
としても存在するため、コンパイル時に失敗しますが、Angular 8コンパイラーは静的に実行できませんプロバイダーのWindow
とコンストラクターのパラメーターのWindow
を関連付けるコード分析。Window
の割り当ては、コードではなくブラウザーによって行われるためです。 Angular 9で動作する理由...
依存関係プロバイダーを表す独自の注入トークンを作成する必要があります。この注入トークンは次のいずれかです。
'Window'
_で行ったように)InjectionToken
。たとえばexport const window = new InjectionToken<Window>('window');
さらに、Angularコードはプラットフォームに依存しない(ブラウザとNode.jsサーバーでも実行可能である必要があります)必要があるため、window
またはundefined
/null
し、コンポーネントのundefined
/null
ケースを処理します。