У меня есть два проекта Angular, использующих эти версии:
- 9.0.0-next.6
- 8.1.0
В версии 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)
}
В чем разница между обеими версиями?
Какая разница в угловых 8 и 9, что вызывает эту вещь?
Ответы:
Для того чтобы ваше приложение работало с рендерингом на стороне сервера, я предлагаю вам не только использовать окно через токен, но и создавать этот токен дружественным по отношению к SSR способом,
window
вообще не ссылаясь на него. Angular имеет встроенныйDOCUMENT
токен для доступаdocument
. Вот что я придумал, чтобы мои проекты использовалиwindow
через токены:источник
Учитывая
ValueProvider
интерфейс: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
case в компонентах.источник