Это работает для меня в настоящее время (2018-03, angular 5.2 с AoT, протестировано в angular-cli и настраиваемой сборке веб-пакета):
Сначала создайте инъекционный сервис, который предоставляет ссылку на window:
import { Injectable } from '@angular/core';
// This interface is optional, showing how you can add strong typings for custom globals.
// Just use "Window" as the type if you don't have custom global stuff
export interface ICustomWindow extends Window {
__custom_global_stuff: string;
}
function getWindow (): any {
return window;
}
@Injectable()
export class WindowRefService {
get nativeWindow (): ICustomWindow {
return getWindow();
}
}
Теперь зарегистрируйте эту службу в корневом модуле AppModule, чтобы ее можно было внедрить везде:
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
а затем позже, куда вам нужно ввести window
:
import { Component} from '@angular/core';
import { WindowRefService, ICustomWindow } from './window-ref.service';
@Component({ ... })
export default class MyCoolComponent {
private _window: ICustomWindow;
constructor (
windowRef: WindowRefService
) {
this._window = windowRef.nativeWindow;
}
public doThing (): void {
let foo = this._window.XMLHttpRequest;
let bar = this._window.__custom_global_stuff;
}
...
Вы также можете захотеть добавить nativeDocument
и другие глобальные переменные к этой службе аналогичным образом, если вы используете их в своем приложении.
edit: Обновлено с предложением Truchainz. edit2: Обновлено для angular 2.1.2 edit3: Добавлены примечания AoT edit4: Добавление any
примечания обходного пути edit5: Обновленное решение для использования WindowRefService, которое исправляет ошибку, которую я получал при использовании предыдущего решения с другой сборкой edit6: добавление примера настраиваемого набора окон
ORIGINAL EXCEPTION: No provider for Window!
. Однако его удаление устранило проблему для меня. Мне было достаточно использовать только первые 2 глобальные строки.@Inject
я получаюNo provider for Window
ошибки. Это очень хорошо, что не требует руководства@Inject
!@Inject(Window)
чтобы это работалоwindow
, но с промежуточной службой он позволяет заглушать нативныйwindow
материал в модульных тестах, и, как вы упомянули, для SSR может быть предоставлена альтернативная служба, которая предоставляет окно макета / noop для сервера. Причина, по которой я упоминаю AOT, - это несколько ранних решений для оборачивания окна в AOT при обновлении Angular.С выпуском angular 2.0.0-rc.5 был представлен NgModule. Предыдущее решение у меня перестало работать. Вот что я сделал, чтобы это исправить:
app.module.ts:
В каком-то компоненте:
Вы также можете использовать OpaqueToken вместо строки Window
Редактировать:
AppModule используется для загрузки вашего приложения в main.ts следующим образом:
Для получения дополнительной информации о NgModule прочтите документацию Angular 2: https://angular.io/docs/ts/latest/guide/ngmodule.html
источник
Вы можете получить окно из внедренного документа.
источник
Вы можете просто ввести его после того, как установили провайдера:
источник
window.var
содержимое страницы, не меняетсяЧтобы заставить его работать на Angular 2.1.1, мне пришлось
@Inject
использовать окно с помощью строкиа потом издеваться над этим вот так
и обычно
@NgModule
я предоставляю это такисточник
В Angular RC4 следующие работы, которые представляют собой комбинацию некоторых из приведенных выше ответов, в вашем корневом приложении app.ts добавьте его в поставщиков:
Затем в вашем сервисе и т. Д. Введите его в конструктор
источник
Перед объявлением @Component это тоже можно сделать,
Компилятор фактически позволит вам получить доступ к глобальной переменной окна, поскольку вы объявляете ее как предполагаемую глобальную переменную с типом any.
Я бы не стал предлагать доступ к окну везде в вашем приложении, однако вам следует создать службы, которые обращаются / изменяют необходимые атрибуты окна (и внедряют эти службы в ваши компоненты), чтобы определить, что вы можете делать с окном, не позволяя им изменять объект всего окна.
источник
Я использовал OpaqueToken для строки Window:
И используется только для импорта
WINDOW_PROVIDERS
в начальной загрузке в Angular 2.0.0-rc-4.Но с выпуском Angular 2.0.0-rc.5 мне нужно создать отдельный модуль:
и только что определен в свойстве import моего основного
app.module.ts
источник
Angular 4 представляет InjectToken, а также создает токен для документа под названием DOCUMENT. . Я думаю, что это официальное решение, и оно работает в AoT.
Я использую ту же логику для создания небольшой библиотеки под названием ngx-window-token, чтобы не повторять это снова и снова.
Я использовал его в другом проекте и без проблем построил AoT.
Вот как я использовал его в другом пакете
Вот плункер
В вашем модуле
imports: [ BrowserModule, WindowTokenModule ]
В вашем компонентеconstructor(@Inject(WINDOW) _window) { }
источник
На сегодняшний день (апрель 2016 г.) код в предыдущем решении не работает, я думаю, что можно вставить окно непосредственно в App.ts, а затем собрать необходимые значения в службу для глобального доступа в приложении, но если вы предпочитаете создавать и внедрять свой собственный сервис, можно найти более простое решение.
https://gist.github.com/WilldelaVega777/9afcbd6cc661f4107c2b74dd6090cebf
источник
Вот еще одно решение, которое я недавно придумал после того, как устал получать
defaultView
отDOCUMENT
встроенного токена и проверять его на null:источник
@Inject(WINDOW) private _window: any
и использовать его как токен внедрения DOCUMENT, предоставленный Angular?Достаточно сделать
и делай
сделать АОТ счастливым
источник
Есть возможность прямого доступа к объекту окна через документ.
источник
Я знаю, что вопрос в том, как внедрить объект окна в компонент, но вы делаете это, кажется, только для того, чтобы добраться до localStorage. Если вам действительно нужен только localStorage, почему бы не использовать службу, которая предоставляет именно это, например h5webstorage . Затем ваш компонент опишет свои реальные зависимости, что сделает ваш код более читабельным.
источник
Это самый короткий / чистый ответ, который я нашел, работая с Angular 4 AOT.
Источник: https://github.com/angular/angular/issues/12631#issuecomment-274260009
источник
Вы можете использовать NgZone на Angular 4:
источник
Также неплохо отметить
DOCUMENT
как необязательный. Согласно документации Angular:Вот пример использования,
DOCUMENT
чтобы узнать, поддерживает ли браузер SVG:источник
@maxisam спасибо за ngx-window-token . Я делал нечто подобное, но переключился на ваше. Это моя служба для прослушивания событий изменения размера окна и уведомления подписчиков.
Коротко и мило и работает как шарм.
источник
Получение оконного объекта через DI (внедрение зависимостей) не является хорошей идеей, когда глобальные переменные доступны во всем приложении.
Но если вы не хотите использовать объект окна, вы также можете использовать
self
ключевое слово, которое также указывает на объект окна.источник
Будьте проще, ребята!
источник
На самом деле очень просто получить доступ к объекту окна, вот мой базовый компонент, и я протестировал его работу
источник