Angular/Typescript全局变量解决方案

前言

在其它前端框架中都有适用于框架本身的状态管理

vue的vuex、react的redux

angular中最为官方的也就是使用Rx

在网上搜索了以下

可以参考 Managing State in Angular 2 Applications ,理论上 Redux 能实现的功能 Rx 当然也都可以

也有 Rx 和 Redux 的组合产品,比如 GitHub - ngrx/store: RxJS powered state management for Angular2 apps, inspired by Redux

1. 前期准备

当然你也可以自己手动撸一个适用于angular2/Typescript的状态管理模块,也就是类似于全局变量的这种

首先要明确一点,在angular中,app-root这个组件是最大的那个父级组件,因此其它的所有组件都是它的子组件

而在angular中组件引用一个服务需要这样:

SomeSharedService.ts

1
2
3
4
5
6
7
8
9
import { Injectable } from '@angular/core'

@Injectable()
export class SomeSharedService {
public globalVar = 'LinDaiDai';
updateGlobaleVar(newVal) {
this.globalVar = newVal;
}
}

app.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Component, OnInit } from '@angular/core';
import { SomeSharedService } from './SomeSharedService';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [SomeSharedService]
})
export class AppComponent implements OnInit{
constructor(
public someSharedService: SomeSharedService
){}
ngOnInit() {
this.getSharedService();
}
getSharedService() {
let info = this.someShareService.golobalVar;
console.log(info);//LinDaiDai
}
}

上面的步骤是创建一个SomeSharedService服务并将其引入到app.component.ts

此时再创建一个子组件

child.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { Component, OnInit } from '@angular/core';
import { SomeSharedService } from './SomeSharedService';

@Component({
selector: 'app-root',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
//providers: [SomeSharedService] //不用在child中的providers引入SomeSharedService
})
export class ChildComponent implements OnInit {
constructor(
public someSharedService: SomeSharedService
){}
ngOnInit() {
this.getSharedService();//先获取
this.updateSharedService();//重新设置新的值
}
getSharedService() {
let info = this.someShareService.globalVar;//LinDaiDai
//do something
}
updateSharedService() {
setTimeout(() => {
this.someShareService.updateSharedService('霖呆呆');
this.getSharedService();//霖呆呆
}, 3000)
}
}

可以看到上面的案例,在子组件中再次引入SomeSharedService但是不要将其注入到子组件的providers中,子组件获取到的golobalVar就不会重新刷新,并且也可以直接改变someShareService中的bianl

此时,在其它的子组件中获取到的someShareService.globalVar就是已经发生改变了的'霖呆呆'

按照这个思路,创建一个自己的全局变量管理就不难了

1.我们只需要定义一个ts文件,里面存放的是一些全局变量

2.在app.component.ts中引用这个ts,并将其加入到appproviders中,不然在控制台中就会报错

3.在要用到全局变量的地方引用这个ts,但不需要在providers中引入,不然会注入新创建的实例

2.自定义的store

如果你是angular/cli Typescript的使用者,请参考以下

1.在app根目录下创建文件夹store,在其中创建俩个文件:store.tsstate.ts

state.ts

1
2
3
4
5
6
import { Injectable } from '@angular/core';

@Injectable()
export class State {
globalVar = {}//某个全局变量
}

state.ts用于保存一些全局变量

store.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { State } from './state';
@Injectable()
export class Store {
constructor(
private http: Http
) {
this.state = new State()
}
state: any;
async getGlobalVar() {
if (!this.state.globalVar) {//若是没有这个全局变量则代表首次获取
this.state.globalVar = await this.thisIsPromise();
return this.state.globalVar;
} else {
return this.state.globalVar;
}
}
async thisIsPromise() {//通过异步请求获取globalVar
await new Promise(() => {
....
})
}
clearState() {
this.state = {...State};//利用解构初始化state
}
}

引入state.ts 并实例化一个state的全局对象

2.在app.component.ts中引入store.ts并添加至providers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
import { Store } from './../app/store/store';
...
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [Store]
})
export class AppComponent {
constructor(
...
public store: Store,
...
) { }
}

3.子组件child.component.ts中引入store.ts不添加至providers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Component, OnInit } from '@angular/core';
import { Store } from './../store/store';

@Component({
selector: 'app-root',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(
public store: Store
){}
ngOnInit() {
this.getSharedService();
}
getGlobalVar() {
let info = this.store.getGlobalVar();
//do something
}
}

此时获取到的store.getGlobalVar()就是全局的变量了

评论