• 【转载】在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
            }
  • 相关阅读:
    实现可重启线程
    让别人能登陆你的mysql
    zmq消息订阅
    git备忘
    【LeetCode】数组排列问题(permutations)(附加next_permutation解析)
    【LeetCode】 数相加组合 Combination Sum
    【LeetCode】【找元素】Find First and Last Position of Element in Sorted Array
    【LeetCode】【数组归并】Merge k Sorted Lists
    【LeetCode】【动态规划】Generate Parentheses(括号匹配问题)
    【Leetcode】Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/sybboy/p/8075146.html
Copyright © 2020-2023  润新知