问题详细描述

我想在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
}

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

  1. JS中声明全局变量

    JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量 ...

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

    <?php function test(){ //定义函数 global $a; //声明全局变量 $a=7; echo "函数内: ".$a . "<br& ...

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

    JavaScript中声明变量很简单var(关键字)+变量名(标识符). 方式1 1 2 var test; var test = 5; 需注意的是该句不能包含在function内,否则是局部变量.这 ...

  4. 教程 - 深度探讨在 Vue3 中引入 CesiumJS 的最佳方式

    目录 1. 你应该先知道的基础知识 1.1. CesiumJS 的库构成 1.2. 选择 Vite3 和 pnpm 的理由 1.3. 使用 External 模式引入静态库 - 不打包静态库 1.4. ...

  5. [golang]使用gomail发邮件(在Go中发送电子邮件的最佳方式)

    1 前言 定义邮箱服务器连接信息,如果是网易邮箱 pass填密码,qq邮箱填授权码(客户端专用密码). gomail包: go get gopkg.in/gomail.v2 更多功能可以参考 http ...

  6. C语言中定义全局变量

    (1)在C语言的头文件中定义变量出现的问题 最好不要傻嘻嘻的在头文件里定义什么东西.比如全局变量: /*xx头文件*/ #ifndef  _XX_头文件.H #define  _XX_头文件.H in ...

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

    JavaScript声明全局变量的三种方式   JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为 ...

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

    JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量 ...

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

    原文地址:http://www.jb51.net/article/36548.htm JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符) ...

随机推荐

  1. django 打印sql语句

    LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'level': 'DE ...

  2. UWP开发砸手机系列(一)—— Accessibility

    因为今天讨论的内容不属于入门系列,所以我把标题都改了.这个啥Accessibility说实话属于及其蛋疼的内容,即如何让视力有障碍的人也能通过声音来使用触屏手机……也许你这辈子也不会接触,但如果有一天 ...

  3. Java基础知识点1

    运算符 运算符的分类: 算术运算符 赋值运算符 关系运算符 逻辑运算符 位运算符 三目运算符 自增自减运算符:++i:i先自加,再做其他运算:i++先运算再自加: --i先自减再做其他运算:i--先运 ...

  4. 索引+sql优化

    索引的概念: 索引是提高查询速度的一种手段.索引有很多种,以下是索引树的结构 要求查询出薪资大于5000的雇员信息,只要在树中找到5000的节点,直接查询该节点右边的数据即可,左边就不用管了,这样提高 ...

  5. 深入了解java虚拟机(JVM) 第七章 内存分配策略

    理解了jvm内存分配策略不仅是程序性能调优的重要知识,还能够给养成自己一种良好的代码思路,一个程序的代码差异往往都是在这里体现出来的. 一.对象优先分配到Eden区域   一般来说,新创建的对象都会直 ...

  6. 前端切图要选择png和jpg呢?

    今天特意验证了一下: 切完图分别保存png24.png8和jpg60.jpg80(60和80表示保存图片时品质选择)后, 然后再压缩图片,压缩图片地址:https://tinypng.com/ 图片直 ...

  7. HBase二级索引的设计

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  8. day 28 :进程相关,进程池,锁,队列,生产者消费者模式

    ---恢复内容开始--- 前情提要: 一:进程Process  1:模块介绍 from multiprocessing import Process from multiprocessing impo ...

  9. leetcode-31-下一个排列

    本题目在凌应标老师的<算法设计与分析>第八次作业中出现,可供参考. 题目描述: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的 ...

  10. Mysql备份之Innobakcupex&Xtrabackup

                       一.innobackupex备份工具 基本选项 --compress:该选项表示压缩innodb数据文件的备份. --compress-threads:该选项表示 ...