【转载】在Angular 2/Typescript中声明全局变量的最佳方式是什么?

问题详细描述

我想在Typescript语言中的Angular 2中声明一些全局可见的变量。最佳的实践方法是?

推荐的实现方法

这是最简单的解决方案,无需使用ServiceObserver

将全局变量放在文件中然后导出它们。

//
// ===== 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

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";

         ...

        }
    }

上述方法是最推荐的的解决方案,原因在于(1)代码简单并且代码量少,(2)不需要你注入一些服务到每个单独的组件或需要放置的地方,也不需要注册。

对上面推荐解决方法的补充

上面提到的方法很不错,不过这里可以稍微改善一下。如果要导出包含所有常量的对象,可以简单地使用es6import模块而不必使用require

另外,还可以使用Object.freeze来使属性成为真实的常量。如果对这个主题有进一步了解的兴趣,可以阅读这篇文章es6-const

// global.ts

 export const GlobalVariable = Object.freeze({
     BASE_API_URL: ‘http://example.com/‘,
     //... more of your variables
 });

使用import引用模块。

//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);
  }
}

更多细节,请参阅以下问题

其他解决思路二

看一个例子Angular 2 - Implementation of shared services(Angular 2 共享服务的实现)

@Injectable()
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);
  }
}

其他解决思路三

首先在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 {
}

其他解决思路四

对于Angular2(v2.2.3)的IMHO,最好的方法是添加包含全局变量的服务,并将其注入到组件中,而不在@Component注释中使用providers标记。通过这种方式,您可以在组件之间共享信息。

拥有全局变量的示例服务:

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的相同实例。如果添加行,则会注入新创建的实例。

补充解决思路一

这不一定是最好的方法,但是如果要在组件中定义全局变量,最简单的方法是使用window变量来写入:

window.GlobalVariable = "what ever!"

您不需要将其传递给引导或导入其他位置,它就可以全局访问所有JS(不仅有angular 2组件)。

补充解决思路二

算是对最推荐方法的补充,使用const关键字,就像在ES6中一样:

//
// ===== File globals.ts
//
‘use strict‘;

export const sep=‘/‘;
export const version: string="22.2.2";

补充解决思路三

如下代码所示的方式:

global.ts

 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
        }
时间: 2024-10-07 03:53:08

【转载】在Angular 2/Typescript中声明全局变量的最佳方式是什么?的相关文章

JS中声明全局变量

JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: 复制代码代码如下: var test = 5;  //全局变量function a(){  var cc=3; //局部变量  alert(test);}function b(){alert(test);} 声明方式二: 没有使用var,直接给标识符test赋值,这样

065-PHP函数中声明全局变量

<?php function test(){ //定义函数 global $a; //声明全局变量 $a=7; echo "函数内: ".$a . "<br>"; } test(); //调用函数 echo "函数外: ".$a; ?> 原文地址:https://www.cnblogs.com/tianpan2019/p/10995284.html

JavaScript声明全局变量三种方式的异同

JavaScript中声明变量格式:var(关键字)+变量名(标识符).方式1var test;var test = 5; 需注意的是该句不能包含在function内,否则是局部变量.这是第一种方式声明全局变量. 方式2test = 5; 没有使用var,直接给标识符test赋值,这样会隐式的声明了全局变量test.即使该语句是在一个function内,当该function被执行后test变成了全局变量. 方式3window.test;window.test = 5; 这种方式经常被用到一个匿名

C语言中定义全局变量

(1)在C语言的头文件中定义变量出现的问题 最好不要傻嘻嘻的在头文件里定义什么东西.比如全局变量: /*xx头文件*/ #ifndef  _XX_头文件.H #define  _XX_头文件.H int A; #endif 那么,很糟糕的是,这里的int A是个全局变量的定义,所以如果这个头文件被多次引用的话,你的A会被重复定义,显然语法上错了.只不过有了这个#ifndef的条件编译,所以能保证你的头文件只被引用一次,不过也许还是不会出岔子,但若多个c文件包含这个头文件时还是会出错的,因为宏名有

js中的全局变量

在js中有3中声明全局变量的方式 第一种使用var+变量名,在方法外部声明: 1 var msg; //默认值undefined 2 $(function(){ 3 setmsg(); 4 showmsg(); 5 }) 6 function setmsg(){ 7 msg = "hello world"; 8 } 9 function showmsg(){ 10 alert(msg); 11 } 第二种方式在方法内部声明,但是不使用var关键字: 1 $(function(){ 2

基于JavaScript 声明全局变量的三种方式详解

JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: var test = 5; //全局变量 function a() { var cc=3; //局部变量 alert(test); } function b(){alert(test);} 声明方式二: 没有使用var,直接给标识符test赋值,这样会隐式的声明了全局

基于JavaScript 声明全局变量的三种方式

本文转自脚本之家:http://www.jb51.net/article/36548.htm JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: 1 <script> 2 var test = 5;//全局变量 3 function a(){ 4 var a = 3;//局部变量 5 alert(a); 6 } 7

JavaScript声明全局变量的三种方式

JavaScript声明全局变量的三种方式 JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: var test = 5; //全局变量 function a() { var cc=3; //局部变量 alert(test); } function b(){alert(test);} 声明方式二: 没有使用var,直接

JavaScript 声明全局变量和局部变量

JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 <script>   var test = 5;//全局变量   function a(){     var a = 3;//局部变量     alert(a);   }   function b(){