Xác định hằng số toàn cầu


258

Trong Angular 1.x bạn có thể định nghĩa các hằng số như thế này:

angular.module('mainApp.config', [])
    .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')

Điều gì sẽ tương đương trong Angular (với TypeScript)?

Tôi chỉ không muốn lặp đi lặp lại url cơ sở API trong tất cả các dịch vụ của mình.

Câu trả lời:


265

Các thay đổi dưới đây hoạt động với tôi trên phiên bản cuối cùng của Angular 2:

export class AppSettings {
   public static API_ENDPOINT='http://127.0.0.1:6666/api/';
}

Và sau đó trong dịch vụ:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(AppSettings.API_ENDPOINT+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}

Tôi nghĩ rằng AppSettingslớp yout nên trừu tượng và API_ENDPOINTthành viên nên được readonly.
Philippe Gioseffi

164

Giải pháp cho cấu hình được cung cấp bởi chính nhóm góc có thể được tìm thấy ở đây .

Đây là tất cả các mã có liên quan:

1) ứng dụng.config.ts

import { OpaqueToken } from "@angular/core";

export let APP_CONFIG = new OpaqueToken("app.config");

export interface IAppConfig {
    apiEndpoint: string;
}

export const AppConfig: IAppConfig = {    
    apiEndpoint: "http://localhost:15422/api/"    
};

2) app.module.ts

import { APP_CONFIG, AppConfig } from './app.config';

@NgModule({
    providers: [
        { provide: APP_CONFIG, useValue: AppConfig }
    ]
})

3) your.service.ts

import { APP_CONFIG, IAppConfig } from './app.config';

@Injectable()
export class YourService {

    constructor(@Inject(APP_CONFIG) private config: IAppConfig) {
             // You can use config.apiEndpoint now
    }   
}

Bây giờ bạn có thể tiêm cấu hình ở mọi nơi mà không cần sử dụng tên chuỗi và với việc sử dụng giao diện của bạn để kiểm tra tĩnh.

Tất nhiên bạn có thể tách Giao diện và hằng số hơn nữa để có thể cung cấp các giá trị khác nhau trong sản xuất và phát triển, vd


3
Nó chỉ hoạt động khi tôi không chỉ định loại trong hàm tạo của dịch vụ. Vì vậy, nó hoạt động khi tôi thực hiện cấu hình riêng tư của nhà xây dựng (@Inject (APP_CONFIG)) {} Có một đề cập về vấn đề này ở đây: blog. Dùtram.io/angular/2016/05/23/, nhưng không phải tại sao.
Mukus

Tôi cho rằng bạn đã bỏ lỡ một số từ khóa nhập hoặc xuất hoặc một cái gì đó tương tự, vì tôi sử dụng nó với giao diện và như bạn nói rất quan trọng để nó được gõ một cách rõ ràng. Có lẽ bạn cần cung cấp ngoại lệ chính xác ở đây.
Ilya Chernomordik

46
Không có giải pháp nào trong số này, ngay cả đội ngũ góc cạnh được đề xuất có vẻ thanh lịch. Tại sao cố gắng tạo hằng số là một quá trình rườm rà trong Angular 2? Bạn có thể thấy Angular1 liền mạch như thế nào không? Tại sao tất cả lộn xộn?
KhoPhi

31
Đối với bất cứ ai khác mà hits câu trả lời này OpaqueToken trong v4 góc là "phản đối" cho InjectionToken - blog.thoughtram.io/angular/2016/05/23/...
mtpultz

3
Sẽ có ý nghĩa khi đặt mã từ Bước 1 vào environment.tsenvironment.prod.tsđể bạn có thể có các hằng số khác nhau cho mỗi môi trường? @IlyaCécomordik bắt đầu đề cập đến điều này trong đoạn cuối câu trả lời của mình.
Robert Bernstein

64

Trong Angular2, bạn có định nghĩa cung cấp sau , cho phép bạn thiết lập các loại phụ thuộc khác nhau:

provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}

So sánh với góc 1

app.servicetrong Angular1 tương đương với useClassAngular2.

app.factorytrong Angular1 tương đương với useFactoryAngular2.

app.constantapp.valueđã được đơn giản hóa useValuevới ít ràng buộc hơn. tức là không còn configkhối nữa.

app.provider - Không có tương đương trong Angular 2.

Ví dụ

Để thiết lập với trình tiêm gốc:

bootstrap(AppComponent,[provide(API_ENDPOINT, { useValue='http://127.0.0.1:6666/api/' })]);

Hoặc thiết lập với trình tiêm thành phần của bạn:

providers: [provide(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})]

provide là tay ngắn cho:

var injectorValue = Injector.resolveAndCreate([
  new Provider(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})
]);

Với kim phun, việc nhận giá trị rất dễ dàng:

var endpoint = injectorValue.get(API_ENDPOINT);

2
Tôi thực sự muốn có các cài đặt của mình trong một tệp bên ngoài, ví dụ: settings.ts Tệp này sẽ trông như thế nào?
AndreFeijo

Bạn đã xem javascript phía máy chủ như NodeJS chưa?
pixelbits

5
Xin lỗi, tôi không hiểu làm thế nào tôi sẽ tiêm nó vào dịch vụ của mình? Khi tôi đang sử dụng một tệp bên ngoài, tôi có cần xuất nó không?
AndreFeijo

Tôi sẽ làm cho nó một phần của quá trình cấu hình xây dựng của bạn. tức là dựa trên môi trường của bạn, biên dịch / gói các tệp khác nhau lại với nhau, sau đó triển khai. Tất cả điều này bạn có thể làm với NodeJS với các mô-đun thích hợp.
pixelbits

1
Thật không may, NodeJS không phải là một lựa chọn.
AndreFeijo

59

Trong Angular 4, bạn có thể sử dụng lớp môi trường để giữ tất cả các phần chung của bạn.

Theo mặc định, bạn có môi trường.ts và môi trường.prod.ts.

Ví dụ

export const environment = {
  production: false,
  apiUrl: 'http://localhost:8000/api/'
};

Và sau đó trên dịch vụ của bạn:

import { environment } from '../../environments/environment';
...
environment.apiUrl;

Nếu bạn đang cố gắng truy cập constvào bên trong một dịch vụ, bạn có thể phải "cung cấp" nó trong mảng nhà cung cấp mô-đun ứng dụng của mình : { provide: 'ConstName', useValue: ConstName }. Tôi đã nhận được một lỗi thời gian chạy mà không có điều này.
daleyjem

@daleyjem đó là vì bạn đã cố gắng tiêm nó. Cách tiếp cận này không sử dụng kim phun
Aluan Haddad

Tạo một hằng số như thế này là đơn giản nhất. Tôi đoán đối số của việc mất DI và do đó mất khả năng kiểm tra / mockValue là một thời gian quá cường điệu. Trong ứng dụng thông thường, chúng tôi sử dụng rất nhiều thành phần không phải DI như (RxJS) mà không làm phiền khả năng kiểm tra.
Amitesh

54

Cập nhật cho góc 4+

Bây giờ chúng ta chỉ cần sử dụng tệp môi trường mà angular cung cấp mặc định nếu dự án của bạn được tạo thông qua angular-cli.

ví dụ

Trong thư mục môi trường của bạn tạo các tệp sau

  • environment.prod.ts
  • environment.qa.ts
  • environment.dev.ts

và mỗi tệp có thể giữ các thay đổi mã liên quan như:

  • environment.prod.ts

    export const environment = {
         production: true,
         apiHost: 'https://api.somedomain.com/prod/v1/',
         CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
  • environment.qa.ts

    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/qa/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
  • environment.dev.ts

    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/dev/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };

Ca sử dụng trong ứng dụng

Bạn có thể nhập môi trường vào bất kỳ tệp nào, chẳng hạn như dịch vụ clientUtilServices.ts

import {environment} from '../../environments/environment';

getHostURL(): string {
    return environment.apiHost;
  }

Ca sử dụng trong bản dựng

Mở tệp cli góc của bạn .angular-cli.jsonvà bên trong "apps": [{...}]thêm mã sau đây

 "apps":[{
        "environments": {
            "dev": "environments/environment.ts",
            "prod": "environments/environment.prod.ts",
            "qa": "environments/environment.qa.ts",
           }
         }
       ]

Nếu bạn muốn xây dựng để sản xuất, hãy chạy ng build --env=prodnó sẽ đọc cấu hình từ đó environment.prod.ts, giống như cách bạn có thể làm cho qahoặcdev

## Câu trả lời cũ hơn

Tôi đã và đang làm một cái gì đó như dưới đây, trong nhà cung cấp của tôi:

import {Injectable} from '@angular/core';

@Injectable()
export class ConstantService {

API_ENDPOINT :String;
CONSUMER_KEY : String;

constructor() {
    this.API_ENDPOINT = 'https://api.somedomain.com/v1/';
    this.CONSUMER_KEY = 'someReallyStupidTextWhichWeHumansCantRead'
  }
}

Sau đó tôi có quyền truy cập vào tất cả dữ liệu liên tục ở bất cứ đâu

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';

import {ConstantService} from  './constant-service'; //This is my Constant Service


@Injectable()
export class ImagesService {
    constructor(public http: Http, public ConstantService: ConstantService) {
    console.log('Hello ImagesService Provider');

    }

callSomeService() {

    console.log("API_ENDPOINT: ",this.ConstantService.API_ENDPOINT);
    console.log("CONSUMER_KEY: ",this.ConstantService.CONSUMER_KEY);
    var url = this.ConstantService.API_ENDPOINT;
    return this.http.get(url)
  }
 }

6
Điều này không hoạt động như một hằng số. Giá trị của hằng số luôn luôn giống nhau. Trong trường hợp của bạn, API_ENDPOINTgiá trị của bạn có thể được ghi đè bất cứ lúc nào. Nếu this.ConstantService.API_ENDPOINT = 'blah blah'được khai báo trong lớp bất cứ lúc nào sau khi cái gọi là "hằng số" của bạn được nhập từ constant-service, thì giá trị mới của API_ENDPOINT sẽ là 'blah blah'. Giải pháp của bạn chỉ cho thấy cách truy cập một biến bằng cách sử dụng một dịch vụ chứ không phải bằng cách sử dụng hằng số.
Devner

1
@Devner chỉ cần làm cho chúng readonly API_ENDPOINT :String;
sẵn sàng

@Anjum Làm thế nào góc cạnh chọn các tập tin env. Tôi có cần phải vượt qua tên env trong khi bắt đầu ứng dụng không?
notionquest

@notionquest Có, bạn có thể vượt qua nó, nhưng build --env=prod
Anjum ....

31

Mặc dù cách tiếp cận với lớp AppSinstall có hằng chuỗi là ApiEndpoint hoạt động, nhưng nó không lý tưởng vì chúng ta sẽ không thể trao đổi ApiEndpoint thực này cho một số giá trị khác tại thời điểm kiểm tra đơn vị.

Chúng tôi cần có khả năng đưa điểm cuối api này vào các dịch vụ của mình (nghĩ đến việc tiêm dịch vụ vào dịch vụ khác). Chúng tôi cũng không cần tạo cả một lớp cho việc này, tất cả những gì chúng tôi muốn làm là đưa một chuỗi vào các dịch vụ của chúng tôi là ApiEndpoint của chúng tôi. Để hoàn thành câu trả lời xuất sắc theo pixelbits , đây là đoạn mã hoàn chỉnh về cách thực hiện trong Angular 2:

Trước tiên, chúng tôi cần cho Angular biết cách cung cấp một phiên bản ApiEndpoint của chúng tôi khi chúng tôi yêu cầu nó trong ứng dụng của chúng tôi (nghĩ về nó như là đăng ký một phụ thuộc):

bootstrap(AppComponent, [
        HTTP_PROVIDERS,
        provide('ApiEndpoint', {useValue: 'http://127.0.0.1:6666/api/'})
]);         


Và sau đó trong dịch vụ, chúng tôi đưa ApiEndpoint này vào nhà xây dựng dịch vụ và Angular sẽ cung cấp nó cho chúng tôi dựa trên đăng ký của chúng tôi ở trên:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable, Inject} from 'angular2/core';  // * We import Inject here
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
                @Inject('ApiEndpoint') private apiEndpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(`${this.apiEndpoint}/messages`)
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    } 
    // the rest of the code...
}

1
Hiện tại có một cách làm "chính thức" được đề xuất bởi đội ngũ góc cạnh trong hướng dẫn của họ. Tôi đã thêm một câu trả lời dưới đây: ( stackoverflow.com/a/40287063/1671558 )
Ilya Chernomordik

1
mã này không còn chính xác nữa, việc thực thi điều này sẽ khiến ApiEndpoint không được tìm thấy trên AppComponent.
WilliamX

Ok vậy tôi không cô đơn. Bạn có biết phiên bản này đã phá vỡ? Có cách nào khác không yêu cầu xác định giá trị trên một đối tượng toàn cầu sau đó cung cấp chúng không?
Jens Bodal

29

Đây là kinh nghiệm gần đây của tôi với kịch bản này:

  • @ góc / cli: 1.0.0
  • nút: 6.10.2
  • @ góc / lõi: 4.0.0

Tôi đã theo dõi các tài liệu chính thức và cập nhật tại đây:

https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#dependency-injection-tokens

Có vẻ OpaqueToken hiện đang bị phản đối và chúng ta phải sử dụng InjectionToken , vì vậy đây là những tác phẩm của tôi chạy như một nét duyên dáng:

app-config.interface.ts

export interface IAppConfig {

  STORE_KEY: string;

}

app-config.constants.ts

import { InjectionToken } from "@angular/core";
import { IAppConfig } from "./app-config.interface";

export const APP_DI_CONFIG: IAppConfig = {

  STORE_KEY: 'l@_list@'

};

export let APP_CONFIG = new InjectionToken< IAppConfig >( 'app.config' );

app.module.ts

import { APP_CONFIG, APP_DI_CONFIG } from "./app-config/app-config.constants";

@NgModule( {
  declarations: [ ... ],
  imports: [ ... ],
  providers: [
    ...,
    {
      provide: APP_CONFIG,
      useValue: APP_DI_CONFIG
    }
  ],
  bootstrap: [ ... ]
} )
export class AppModule {}

my-service.service.ts

  constructor( ...,
               @Inject( APP_CONFIG ) private config: IAppConfig) {

    console.log("This is the App's Key: ", this.config.STORE_KEY);
    //> This is the App's Key:  l@_list@

  }

Kết quả là rõ ràng và không có cảnh báo nào trên bảng điều khiển cảm ơn bình luận gần đây của John Papa về vấn đề này:

https://github.com/angular/angular-cli/issues/2034

Khóa được thực hiện trong một tệp khác giao diện.


xem thêm stackoverflow.com/a/43193574/3092596 - về cơ bản là giống nhau, nhưng tạo ra các mô-đun có thể tiêm thay vì nhà cung cấp
goredwards

19

Tất cả các giải pháp dường như là phức tạp. Tôi đang tìm giải pháp đơn giản nhất cho trường hợp này và tôi chỉ muốn sử dụng hằng số. Hằng số rất đơn giản. Có bất cứ điều gì nói chống lại giải pháp sau đây?

app.const.ts

'use strict';

export const dist = '../path/to/dist/';

app.service.ts

import * as AppConst from '../app.const'; 

@Injectable()
export class AppService {

    constructor (
    ) {
        console.log('dist path', AppConst.dist );
    }

}

2
Chà, bạn đang sử dụng các biến ngoài phạm vi của dịch vụ để bạn cũng có thể sử dụng các cửa sổ toàn cầu sau đó. Những gì chúng tôi đang cố gắng làm là đưa các hằng số vào hệ thống tiêm phụ thuộc Angular4 để chúng tôi có thể giữ phạm vi sạch sẽ, ổn định hoặc có thể chế giễu.
Joel Hernandez

11

Chỉ cần sử dụng hằng số bản in

export var API_ENDPOINT = 'http://127.0.0.1:6666/api/';

Bạn có thể sử dụng nó trong trình tiêm phụ thuộc bằng cách sử dụng

bootstrap(AppComponent, [provide(API_ENDPOINT, {useValue: 'http://127.0.0.1:6666/api/'}), ...]);

1
Tại sao phải tiêm nó? Tôi không cần điều đó ... tôi có thể sử dụng nó ngay khi bạn nhập nó. @SnareChops
Sasxa

@Sasxa Tôi đồng ý, mặc dù nó có thể tốt cho thử nghiệm đơn vị và như vậy. Chỉ cần cố gắng để cung cấp một câu trả lời đầy đủ.
SnareChops

1
@Andreas Bạn có thể sử dụng constyest
SnareChops

Vui lòng cung cấp một stackblitz của công việc này. Tôi đã thấy rất nhiều ví dụ về việc cung cấp một dịch vụ trong phương thức bootstrap nhưng vẫn chưa tìm thấy một ví dụ nào có ví dụ hoạt động đầy đủ. Có thể một cái gì đó đã thay đổi trong một phiên bản góc cạnh gần đây hơn.
Jens Bodal

4

Nếu bạn đang sử dụng Webpack , mà tôi khuyên dùng, bạn có thể thiết lập các hằng số cho các môi trường khác nhau. Điều này đặc biệt có giá trị khi bạn có các giá trị không đổi khác nhau trên cơ sở môi trường.

Bạn có thể có nhiều tệp webpack trong /configthư mục của mình (ví dụ: webpack.dev.js, webpack.prod.js, v.v.). Sau đó, bạn sẽ có một custom-typings.d.tsbạn sẽ thêm chúng ở đó. Đây là mẫu chung để theo dõi trong mỗi tệp và cách sử dụng mẫu trong Thành phần.

gói web. {env} .js

const API_URL = process.env.API_URL = 'http://localhost:3000/';
const JWT_TOKEN_NAME = "id_token";
...
    plugins: [
      // NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
      new DefinePlugin({
        'API_URL': JSON.stringify(API_URL),
        'JWT_TOKEN_NAME': JSON.stringify(JWT_TOKEN_NAME)
      }),

kiểu chữ tùy chỉnh.d.ts

declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment {
  API_URL: string;
  JWT_TOKEN_NAME: string;
}

Thành phần

export class HomeComponent implements OnInit {
  api_url:string = API_URL;
  authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME)});
}

3

Sử dụng tệp thuộc tính được tạo trong quá trình xây dựng rất đơn giản và dễ dàng. Đây là cách tiếp cận mà Angular CLI sử dụng. Xác định tệp thuộc tính cho từng môi trường và sử dụng lệnh trong quá trình xây dựng để xác định tệp nào được sao chép vào ứng dụng của bạn. Sau đó, chỉ cần nhập tệp thuộc tính để sử dụng.

https://github.com/angular/angular-cli#build-target-and-envir-files


3

Một cách tiếp cận cho Angular4 sẽ là xác định hằng số ở cấp độ mô-đun:

const api_endpoint = 'http://127.0.0.1:6666/api/';

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    MessageService,
    {provide: 'API_ENDPOINT', useValue: api_endpoint}
  ]
})
export class AppModule {
}

Sau đó, trong dịch vụ của bạn:

import {Injectable, Inject} from '@angular/core';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
      @Inject('API_ENDPOINT') private api_endpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(this.api_endpoint+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}

3

Tôi có một cách khác để xác định hằng số toàn cầu. Bởi vì nếu chúng ta xác định trong tệp ts, nếu xây dựng trong chế độ sản xuất, không dễ tìm thấy các hằng số để thay đổi giá trị.

export class SettingService  {

  constructor(private http: HttpClient) {

  }

  public getJSON(file): Observable<any> {
      return this.http.get("./assets/configs/" + file + ".json");
  }
  public getSetting(){
      // use setting here
  }
}

Trong thư mục ứng dụng, tôi thêm cấu hình thư mục / settings.json

Nội dung trong settings.json

{
    "baseUrl": "http://localhost:52555"
}

Trong mô-đun ứng dụng, hãy thêm APP_INITIALIZER

   {
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() {return setting.getSetting()},
      deps: [SettingService],
      multi: true
    }

với cách này, tôi có thể thay đổi giá trị trong tệp json dễ dàng hơn. Tôi cũng sử dụng cách này cho các thông báo lỗi / cảnh báo liên tục.


0

AngularJS module.constantkhông định nghĩa một hằng số theo nghĩa chuẩn.

Mặc dù nó đứng riêng như một cơ chế đăng ký của nhà cung cấp, nhưng nó được hiểu rõ nhất trong ngữ cảnh của hàm module.value( $provide.value) có liên quan . Tài liệu chính thức nêu rõ trường hợp sử dụng:

Đăng ký một dịch vụ giá trị với $ kim phun, chẳng hạn như chuỗi, số, mảng, đối tượng hoặc hàm. Đây là viết tắt của việc đăng ký một dịch vụ trong đó tài sản $ get của nhà cung cấp là một chức năng của nhà máy không có đối số và trả về dịch vụ giá trị. Điều đó cũng có nghĩa là không thể tiêm các dịch vụ khác vào một dịch vụ giá trị.

So sánh điều này với tài liệu cho module.constant( $provide.constant) cũng nêu rõ trường hợp sử dụng (nhấn mạnh của tôi):

Đăng ký một dịch vụ không đổi với $ kim phun, chẳng hạn như chuỗi, số, mảng, đối tượng hoặc hàm. Giống như giá trị, không thể tiêm các dịch vụ khác vào một hằng số. Nhưng không giống như giá trị, một hằng số có thể được đưa vào một hàm cấu hình mô-đun (xem angular.Module) và nó không thể bị ghi đè bởi một trình trang trí AngularJS .

Do đó, constanthàm AngularJS không cung cấp một hằng số theo nghĩa thông thường được hiểu của thuật ngữ trong lĩnh vực này.

Điều đó nói rằng các hạn chế được đặt trên đối tượng được cung cấp, cùng với tính khả dụng trước đó của nó thông qua trình tiêm $, rõ ràng gợi ý rằng tên này được sử dụng bởi sự tương tự.

Nếu bạn muốn một hằng số thực tế trong ứng dụng AngularJS, bạn sẽ "cung cấp" một cách giống như bạn làm trong bất kỳ chương trình JavaScript nào

export const π = 3.14159265;

Trong Angular 2, kỹ thuật tương tự được áp dụng.

Các ứng dụng Angular 2 không có giai đoạn cấu hình theo nghĩa tương tự như các ứng dụng AngularJS. Hơn nữa, không có cơ chế trang trí dịch vụ ( AngularJS Decorator ) nhưng điều này không đặc biệt đáng ngạc nhiên khi chúng khác nhau như thế nào.

Ví dụ về

angular
  .module('mainApp.config', [])
  .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');

là tùy ý mơ hồ và hơi lạc quan vì $provide.constantđang được sử dụng để chỉ định một đối tượng tình cờ cũng là một hằng số. Bạn cũng có thể đã viết

export const apiEndpoint = 'http://127.0.0.1:6666/api/';

cho tất cả hoặc có thể thay đổi.

Bây giờ, đối số cho khả năng kiểm tra, chế nhạo hằng số, bị giảm đi vì nó thực sự không thay đổi.

Người ta không chế nhạo π.

Tất nhiên ngữ nghĩa cụ thể của ứng dụng của bạn có thể là điểm cuối của bạn có thể thay đổi hoặc API của bạn có thể có cơ chế chuyển đổi dự phòng không minh bạch, do đó, sẽ rất hợp lý khi điểm cuối API thay đổi trong một số trường hợp nhất định.

Nhưng trong trường hợp đó, việc cung cấp nó dưới dạng chuỗi đại diện theo nghĩa đen của một URL duy nhất cho constanthàm sẽ không hoạt động.

Một lập luận tốt hơn và có khả năng phù hợp hơn với lý do tồn tại của $provide.constanthàm AngularJS là, khi AngularJS được giới thiệu, JavaScript không có khái niệm mô-đun chuẩn . Trong trường hợp đó, toàn cầu sẽ được sử dụng để chia sẻ các giá trị, có thể thay đổi hoặc không thay đổi và sử dụng toàn cầu là vấn đề.

Điều đó nói rằng, cung cấp một cái gì đó như thế này thông qua một khung làm tăng khớp nối với khung đó. Nó cũng trộn lẫn logic cụ thể Angular với logic sẽ hoạt động trong bất kỳ hệ thống nào khác.

Đây không phải là một cách tiếp cận sai hay có hại, nhưng cá nhân tôi, nếu tôi muốn có một hằng số trong ứng dụng Angular 2, tôi sẽ viết

export const π = 3.14159265;

giống như tôi đã sử dụng AngularJS.

Càng nhiều thứ thay đổi ...


0

Cách tốt nhất để tạo các hằng số ứng dụng rộng trong Angular 2 là sử dụng các tệp môi trường. Ưu điểm của việc khai báo các hằng số như vậy là bạn có thể thay đổi chúng theo môi trường vì có thể có một tệp môi trường khác nhau cho mỗi môi trường.


Điều này không hoạt động nếu bạn có ý định xây dựng ứng dụng của mình một lần rồi triển khai nó đến nhiều môi trường.
Jens Bodal

-1

Bạn có thể tạo một lớp cho biến toàn cục của mình và sau đó xuất lớp này như thế này:

export class CONSTANT {
    public static message2 = [
        { "NAME_REQUIRED": "Name is required" }
    ]

    public static message = {
        "NAME_REQUIRED": "Name is required",
    }
}

Sau khi tạo và xuất CONSTANTlớp của bạn , bạn nên nhập lớp này trong lớp đó nơi bạn muốn sử dụng, như thế này:

import { Component, OnInit                       } from '@angular/core';
import { CONSTANT                                } from '../../constants/dash-constant';


@Component({
  selector   : 'team-component',
  templateUrl: `../app/modules/dashboard/dashComponents/teamComponents/team.component.html`,
})

export class TeamComponent implements OnInit {
  constructor() {
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }

  ngOnInit() {
    console.log("oninit");
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }
}

Bạn có thể sử dụng phương pháp này trong constructorhoặc ngOnInit(){}, hoặc trong bất kỳ phương pháp xác định trước nào.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.