如何将窗口注入服务?

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

我怎么做?

乐米亚2020/05/28 14:54:23

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

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

飞云2020/05/28 14:54:23

保持简单,伙计们!

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

<div>{{window.Object.entries({ foo: 1 }) | json}}</div>
宝儿理查德2020/05/28 14:54:23

这是我在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 14:54:23

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

村村2020/05/28 14:54:23

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

document.defaultView == window
Gil2020/05/28 14:54:23

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

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

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

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

这是the

在您的模块中

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

constructor(@Inject(WINDOW) _window) { }

2020/05/28 14:54:22

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

declare var window: any;

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

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