【转载】在Angular 2/Typescript中声明全局变量的最佳方式是什么?
问题详细描述
我想在Typescript
语言中的Angular 2
中声明一些全局可见的变量。最佳的实践方法是?
推荐的实现方法
这是最简单的解决方案,无需使用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
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中声明全局变量的最佳方式是什么?的更多相关文章
- JS中声明全局变量
JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量 ...
- 065-PHP函数中声明全局变量
<?php function test(){ //定义函数 global $a; //声明全局变量 $a=7; echo "函数内: ".$a . "<br& ...
- JavaScript声明全局变量三种方式的异同
JavaScript中声明变量很简单var(关键字)+变量名(标识符). 方式1 1 2 var test; var test = 5; 需注意的是该句不能包含在function内,否则是局部变量.这 ...
- 教程 - 深度探讨在 Vue3 中引入 CesiumJS 的最佳方式
目录 1. 你应该先知道的基础知识 1.1. CesiumJS 的库构成 1.2. 选择 Vite3 和 pnpm 的理由 1.3. 使用 External 模式引入静态库 - 不打包静态库 1.4. ...
- [golang]使用gomail发邮件(在Go中发送电子邮件的最佳方式)
1 前言 定义邮箱服务器连接信息,如果是网易邮箱 pass填密码,qq邮箱填授权码(客户端专用密码). gomail包: go get gopkg.in/gomail.v2 更多功能可以参考 http ...
- C语言中定义全局变量
(1)在C语言的头文件中定义变量出现的问题 最好不要傻嘻嘻的在头文件里定义什么东西.比如全局变量: /*xx头文件*/ #ifndef _XX_头文件.H #define _XX_头文件.H in ...
- JavaScript声明全局变量的三种方式
JavaScript声明全局变量的三种方式 JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为 ...
- JavaScript 声明全局变量和局部变量
JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量 ...
- 基于JavaScript 声明全局变量的三种方式详解
原文地址:http://www.jb51.net/article/36548.htm JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符) ...
随机推荐
- ie11下ajax用escape发送中文参数失败
一个项目中,登录请求是ajax,get模式.登录名无中文可以正常登录:登录名是中文则偶尔可以登录,大部分情况下无法登录,ajax请求无法发送成功. 登录名是用js的escape函数转码. 经过多次测试 ...
- 关于My Sql update语句不能用子查询的解决办法
在使用My Sql数据库语法操作update时,第一时间想到的是一下写法: UPDATE purchase_request_detail SET convert_to_voucher_id=, con ...
- WCF实现进程间管道通信Demo
一.代码结构: 二.数据实体类: using System; using System.Collections.Generic; using System.Linq; using System.Run ...
- Java NIO Selector选择器
Selector是Java NIO中的一个组件,用于检查一个或多个NIO Channel的状态是否处于可读.可写.如此可以实现单线程管理多个channels,也就是可以管理多个网络链接. 为什么使用S ...
- linux 使用内存作为 /tmp 临时文件夹
方法一:cat /etc/fstabtmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0 方法二:mount tmpfs /tmp -t tmpfs -o s ...
- 微信小店调用api代码示例
刚开始调用微信小店api的时候,可能大家会遇到问题.系统总是提示system error,归根结底还是发送的参数不正确. 下面给出几个调用例子: 例子写得不全. <?php function c ...
- Centos7.4下安装Nginx
一.下载Nginx Nginx下载地址:http://nginx.org/en/download.html Nginx是C语言开发的,建议在Linux上运行.由于Nginx的一些模块依赖一些lib,所 ...
- elasticsearch 基础笔记
基础: 1.查看 所有节点,及版本 http://192.168.18.7:9200/_nodes/_all/version?pretty=true
- Mac下安装JDK(Mac 10.12)
1.到官网http://www.oracle.com/technetwork/java/javase/downloads/index.html下载JDK 2.安装 打开dmg包 3.测试 在终端上输入 ...
- [Xamarin] 製作吐司(Toast)以及圖文並茂的Toast (转帖)
最近在看Xamarin使用C#來撰寫Android App . 紀錄一下,順便給之後有需要的人可以有所參考 :) 今天要來聊的是關於Toast 這東西,這在以前Android 上面我是很常使用 拿來l ...