我想一些变量来进行访问无处不在Angular 2
的Typescript
语言。我应该如何去实现呢?
Uncaught ReferenceError: Settings is not defined
。Settings
具有公共静态变量的类设置为export并已在其使用位置导入。
我想一些变量来进行访问无处不在Angular 2
的Typescript
语言。我应该如何去实现呢?
Uncaught ReferenceError: Settings is not defined
。Settings
具有公共静态变量的类设置为export并已在其使用位置导入。
Answers:
这是最简单的解决方案,Service
没有/ 也没有Observer
:
将全局变量放在文件中,然后导出它们。
//
// ===== File globals.ts
//
'use strict';
export const sep='/';
export const version: string="22.2.2";
要在另一个文件中使用全局变量,请使用以下import
语句:
import * as myGlobals from 'globals';
例:
//
// ===== File heroes.component.ts
//
import {Component, OnInit} from 'angular2/core';
import {Router} from 'angular2/router';
import {HeroService} from './hero.service';
import {HeroDetailComponent} from './hero-detail.component';
import {Hero} from './hero';
import * as myGlobals from 'globals'; //<==== this one (**Updated**)
export class HeroesComponent implements OnInit {
public heroes: Hero[];
public selectedHero: Hero;
//
//
// Here we access the global var reference.
//
public helloString: string="hello " + myGlobals.sep + " there";
...
}
}
谢谢@ eric-martinez
import * as globs from 'globals'
export const
,而不是export var
-你真的想确保这些全局变量不能被改变
import * as myGlobals from 'globals'
import * as myGlobals from './path/to/globals';
我也喜欢@supercobra的解决方案。我只是想稍微改善一下。如果导出包含所有常量的对象,则只需使用es6 import模块即可,而无需使用require。
我还使用了Object.freeze来使属性成为真正的常数。如果您对该主题感兴趣,可以阅读这篇文章。
// global.ts
export const GlobalVariable = Object.freeze({
BASE_API_URL: 'http://example.com/',
//... more of your variables
});
使用导入引用模块。
//anotherfile.ts that refers to global constants
import { GlobalVariable } from './path/global';
export class HeroService {
private baseApiUrl = GlobalVariable.BASE_API_URL;
//... more code
}
共享服务是最好的方法
export class SharedService {
globalVar:string;
}
但是注册时需要非常小心,以便能够为整个应用程序共享一个实例。注册应用程序时需要定义它:
bootstrap(AppComponent, [SharedService]);
但不要在providers
组件的属性中再次定义它:
@Component({
(...)
providers: [ SharedService ], // No
(...)
})
否则,将为组件及其子组件创建服务的新实例。
您可以看一下有关Angular2中依赖项注入和分层注入器如何工作的问题:
您会注意到,还可以Observable
在服务中定义属性,以在全局属性更改时通知应用程序的各个部分:
export class SharedService {
globalVar:string;
globalVarUpdate:Observable<string>;
globalVarObserver:Observer;
constructor() {
this.globalVarUpdate = Observable.create((observer:Observer) => {
this.globalVarObserver = observer;
});
}
updateGlobalVar(newValue:string) {
this.globalVar = newValue;
this.globalVarObserver.next(this.globalVar);
}
}
有关更多详细信息,请参见此问题:
HTTP_PROVIDERS
和类似的,应该也不会被添加到bootstrap()
?
bootstrap()
但实际上并不重要。我认为列出它们boostrap()
使代码更易于理解。组件具有提供程序,指令,模板。我发现这里也没有列出全球供应商,因此过载了。因此我更喜欢bootstrap()
。
alert(globalVar)
导致错误。
@Injectable()
export class MyGlobals {
readonly myConfigValue:string = 'abc';
}
@NgModule({
providers: [MyGlobals],
...
})
class MyComponent {
constructor(private myGlobals:MyGlobals) {
console.log(myGlobals.myConfigValue);
}
}
或提供个人价值
@NgModule({
providers: [{provide: 'myConfigValue', useValue: 'abc'}],
...
})
class MyComponent {
constructor(@Inject('myConfigValue') private myConfigValue:string) {
console.log(myConfigValue);
}
}
bootstrap()
。bootstrap()
和根组件是两个不同的东西。调用时,您将bootstrap(AppComponent, [MyService])
在其中注册服务,boostrap()
它AppComponent
是根组件。文档提到某个地方,它providers: ['MyService']
倾向于在根组件中注册提供程序(服务),但是我还没有发现赞成或反对bootstrap()
根组件的任何论点。
在app / globals.ts中创建Globals类:
import { Injectable } from '@angular/core';
Injectable()
export class Globals{
VAR1 = 'value1';
VAR2 = 'value2';
}
在您的组件中:
import { Globals } from './globals';
@Component({
selector: 'my-app',
providers: [ Globals ],
template: `<h1>My Component {{globals.VAR1}}<h1/>`
})
export class AppComponent {
constructor(private globals: Globals){
}
}
注意:您可以将Globals服务提供程序直接添加到模块中,而不是组件中,而无需将其作为提供程序添加到该模块中的每个组件中。
@NgModule({
imports: [...],
declarations: [...],
providers: [ Globals ],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
Globals
的同时添加它providers: [ ... ]
意味着您不能在一个组件内更改值,然后在第二个组件内要求更新后的值。每次注入Globals
时都是一个新实例。如果要更改此行为,只需不添加Globals
为提供者即可。
@Injectable()
IMHO for Angular2(v2.2.3)的最佳方法是添加包含全局变量的服务,并将其注入到组件中,而组件中没有providers
标签。@Component
注释中。这样,您就可以在组件之间共享信息。
拥有全局变量的样本服务:
import { Injectable } from '@angular/core'
@Injectable()
export class SomeSharedService {
public globalVar = '';
}
一个示例组件,用于更新全局变量的值:
import { SomeSharedService } from '../services/index';
@Component({
templateUrl: '...'
})
export class UpdatingComponent {
constructor(private someSharedService: SomeSharedService) { }
updateValue() {
this.someSharedService.globalVar = 'updated value';
}
}
读取全局变量值的样本组件:
import { SomeSharedService } from '../services/index';
@Component({
templateUrl: '...'
})
export class ReadingComponent {
constructor(private someSharedService: SomeSharedService) { }
readValue() {
let valueReadOut = this.someSharedService.globalVar;
// do something with the value read out
}
}
请注意,
providers: [ SomeSharedService ]
不应将其添加到@Component
注释中。通过不添加此行注入,将始终为您提供的相同实例SomeSharedService
。如果添加该行,则将注入新创建的实例。
Unhandled Promise rejection: No provider for SomeSharedService
providers: [SomeSharedService]
父模块文件。谢谢。
我不知道最好的方法,但是如果要在组件内部定义全局变量,最简单的方法是使用window
变量编写如下:
window.GlobalVariable = "what ever!"
您无需将其传递到引导程序或将其导入其他地方,并且所有JS(不仅是angular 2组件)都可以全局访问。
我就是这样使用的:
全球
export var server: string = 'http://localhost:4200/';
export var var2: number = 2;
export var var3: string = 'var3';
使用它就像这样导入:
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import * as glob from '../shared/global'; //<== HERE
@Injectable()
export class AuthService {
private AuhtorizationServer = glob.server
}
编辑:删除“ _”作为建议的前缀。
我认为最好的方法是通过在需要的地方导出和导入对象,在整个应用程序中与全局变量共享一个对象。
首先创建一个新的.ts文件,例如globals.ts并声明一个对象。我给它提供了一个对象类型,但您也可以使用任何类型或{}
export let globalVariables: Object = {
version: '1.3.3.7',
author: '0x1ad2',
everything: 42
};
之后导入
import {globalVariables} from "path/to/your/globals.ts"
并使用它
console.log(globalVariables);