如何将窗口注入服务?

角度的 TypeScript

猴子

2020-05-28

我正在TypeScript中编写Angular 2服务,该服务将使用localstorage我想将对浏览器window对象的引用注入到我的服务中,因为我不想引用任何全局变量,例如Angular1.x $window

我怎么做?

第4202篇《如何将窗口注入服务?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

7个回答
乐米亚 2020.05.28

当在整个应用程序中都可以访问全局变量时,通过DI(依赖注入)获取窗口对象不是一个好主意。

但是,如果您不想使用窗口对象,则还可以使用self也指向窗口对象的关键字。

飞云 2020.05.28

保持简单,伙计们!

export class HeroesComponent implements OnInit {
  heroes: Hero[];
  window = window;
}

<div>{{window.Object.entries({ foo: 1 }) | json}}</div>
宝儿理查德 2020.05.28

这是我在Angular 4 AOT中找到的最短/最简洁的答案

来源:https : //github.com/angular/angular/issues/12631#issuecomment-274260009

@Injectable()
export class WindowWrapper extends Window {}

export function getWindow() { return window; }

@NgModule({
  ...
  providers: [
    {provide: WindowWrapper, useFactory: getWindow}
  ]
  ...
})
export class AppModule {
  constructor(w: WindowWrapper) {
    console.log(w);
  }
}
伽罗理查德 2020.05.28

我知道问题是如何将窗口对象注入到组件中,但您这样做似乎只是为了进入localStorage。如果您确实只需要localStorage,为什么不使用公开了该服务的服务,例如h5webstorage然后,您的组件将描述其真正的依赖关系,这将使您的代码更具可读性。

村村 2020.05.28

有机会通过文档直接访问窗口对象

document.defaultView == window
Gil 2020.05.28

Angular 4引入了InjectToken,并且它们还为文档创建了一个称为DOCUMENT的令牌我认为这是官方解决方案,并且可以在AoT中使用。

我使用相同的逻辑来创建一个名为ngx-window-token的小型库,以防止重复执行此操作。

我在其他项目中使用了它,并在AoT中进行了构建,没有任何问题。

这是我在其他包装中使用的方式

这是the

在您的模块中

imports: [ BrowserModule, WindowTokenModule ] 在你的组件中

constructor(@Inject(WINDOW) _window) { }

2020.05.28

在@Component声明之前,您也可以这样做,

declare var window: any;

编译器实际上将允许您立即访问全局窗口变量,因为您将其声明为类型为any的假定全局变量。

我不建议您在应用程序中的任何地方访问窗口,您应该创建访问/修改所需窗口属性的服务(并将这些服务注入到组件中),以限制您可以对窗口执行的操作,而不允许它们修改窗口。整个窗口对象。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android