Angular 4/5/6全局变量


115

我真的很难在Angular 2应用程序中创建全局变量。

在过去的3个小时中,我已经在Google上搜索并阅读了关于StackOverflow的许多帖子,但是似乎我无法使其正常运行。我真的希望您能为我提供帮助,对于这个问题,我深表歉意。

因此,我有一个名为globals.ts的文件,如下所示:

import { Injectable } from "@angular/core";


@Injectable()
export class Globals {

  var role = 'test';

}

我想在组件的HTML视图中使用变量角色,如下所示:

{{ role }} 

我已经通过以下方式将globals.ts文件添加到我的app.module.ts中:

providers: [
  Globals
],

不管我对该文件做了什么,它都没有用。我不想做的是必须手动在每个组件中导入globals.ts文件,这就是为什么我要使用提供程序功能。

我真的希望您能帮助我,再次对不起。

最好的祝福,

自动曝光


4
export class Globals { var role = 'test'; }<-那是什么?
zerkms '17

那应该是我想在其中存储全局变量的Globals类。例如,变量“ role”(现在应该在其中包含字符串“ test”)只是为了测试全局变量是否起作用。
AE

它不是有效的打字稿。
zerkms '17

我应该删除“ var”吗?
AE

那使用localStorage呢?
suhailvs

Answers:


179

您可以Globals通过Angular依赖注入从应用程序的任何位置访问实体。如果要Globals.role在某个组件的模板中输出值,则应Globals像任何服务一样通过该组件的构造函数注入:

// hello.component.ts
import { Component } from '@angular/core';
import { Globals } from './globals';

@Component({
  selector: 'hello',
  template: 'The global role is {{globals.role}}',
  providers: [ Globals ] // this depends on situation, see below
})

export class HelloComponent {
  constructor(public globals: Globals) {}
}

Globals在中提供了HelloComponent,但可以在某些HelloComponent's父组件中甚至在中提供它AppModule。直到Globals只有静态数据无法更改(例如,仅常量),这才无关紧要。但是,如果这不是真的,例如,不同的组件/服务可能想要更改该数据,则Globals必须为单例。在这种情况下,应在将要使用它的层次结构的最高级别中提供它。假设这是AppModule

import { Globals } from './globals'

@NgModule({
  // ... imports, declarations etc
  providers: [
    // ... other global providers
    Globals // so do not provide it into another components/services if you want it to be a singleton
  ]
})

另外,不可能像以前那样使用var,应该

// globals.ts
import { Injectable } from '@angular/core';

@Injectable()
export class Globals {
  role: string = 'test';
}

更新资料

最后,我在stackblitz上创建了一个简单的演示,其中Globals3个组件之间共享单个组件,其中一个组件可以更改的值Globals.role


3
但是,当我在另一个组件(something = globals.role;)中获得它时,我得到了“测试”。而不是我为其分配的值。
punkouter

3
@punkouter我使用Plunker演示链接更新了答案。希望对您有帮助!
dhilt

3
这有点老了,但我只想说我爱你。拯救了我的一天!
Nie Selam

2
@AtulStha我刚刚将演示从Plunker转移到Stackblitz,感谢您的关注。
dhilt

1
@GauravSachdeva您可以将问题作为一个单独的问题发布,这样,我相信这将是最佳选择。如果您希望我看到它,请在评论中添加链接。
dhilt

22

我为此使用环境。它会自动运行,您不必创建新的可注入服务,这对我来说最有用,不需要通过构造函数导入。

1)在您的environment.ts中创建环境变量

export const environment = {
    ...
    // runtime variables
    isContentLoading: false,
    isDeployNeeded: false
}

2)在* .ts文件中导入environment.ts 并创建可在html模板中使用的公共变量(即“ env”)

import { environment } from 'environments/environment';

@Component(...)
export class TestComponent {
    ...
    env = environment;
}

3)在模板中使用...

<app-spinner *ngIf='env.isContentLoading'></app-spinner>

在* .ts中...

env.isContentLoading = false 

(或者只是environment.isContentLoading,以防模板不需要它)


您可以在environment.ts中创建自己的全局变量集,如下所示:

export const globals = {
    isContentLoading: false,
    isDeployNeeded: false
}

并直接导入这些变量(y)


1
当您进行生产构建时该怎么办?你在两个地方都有东西吗?
Mulperi

2
这是最好的方法。@Mulperi不需要在environment.ts中创建全局变量。只需在应用目录中创建具有上述导出功能的globals.ts,然后将此文件导入您要使用这些全局变量的位置即可。
PrasadW

1
我同意。我最近像@PrasadW指出的那样修改了此解决方案。
马丁·斯拉夫科夫斯基

现在,默认情况下,新的Angular版本确实使用该方法。有一个environments/environment.tsenvironments/environment.prod.ts被自动替换。
地毯

0

不太推荐,但其他答案都不是全局变量。对于真正的全局变量,您可以执行此操作。

Index.html

<body>
  <app-root></app-root>
  <script>
    myTest = 1;
  </script>
</body>

组件或Angular中的任何其他内容

..进口后右上角附近:

declare const myTest: any;

...后来:

console.warn(myTest); // outputs '1'

-2

您可以使用Window对象并在任何地方访问它。例如window.defaultTitle =“我的标题”; 那么您就可以访问window.defaultTitle而不导入任何内容。


这是它想要避免的。
Scandinave
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.