typescript - دسترسی به متغیرهای محیطی در نسخه تولیدی Angular 4
من میخواهم یک نسخه تولیدی از برنامه انگولار را با یک URL API قابل تنظیم برای کاربر به منظور آزمایش آن منتشر کنم. من از environment.ts استفاده میکنم، اما بعد از ساخت تولید، نمیدانم چگونه متغیرها را تنظیم کنم.
چه رویکردی باید انجام شود؟
پاسخ شماره ۱
فایل environment*.ts شامل پیکربندیهای زمان ساخت است که پس از ساخت نمیتوانید آنها را تغییر دهید. اگر نیاز دارید پیکربندی خود را پس از ساخت تغییر دهید، باید آنها را در مکان دیگری قرار دهید و هنگام شروع برنامه به طور پویا بازیابی کنید.
کاری که میتوانید انجام دهید این است:
مرحله #1: فایلهای پیکربندی json خود را در مسیر src/assets/config/[envName].json قرار دهید.
توجه: باید فرمت json باشد، نه فرمت ts
مرحله #2: اضافه کردن یک سرویس پیکربندی جدید
import {Inject, Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {Observable} from 'rxjs/Rx';
import {environment} from "../../environments/environment";
/**
* Declaration of config class
*/
export class AppConfig
{
//Your properties here
readonly production: boolean;
readonly name: string;
readonly apiBaseUrl: string;
}
/**
* Global variable containing actual config to use. Initialised via ajax call
*/
export let APP_CONFIG: AppConfig;
/**
* Service in charge of dynamically initialising configuration
*/
@Injectable()
export class AppConfigService
{
constructor(private http: HttpClient)
{
}
public load()
{
return new Promise((resolve, reject) => {
let confName = environment.name + '.json';
this.http.get('/assets/config/' + confName).map(res => res as any).catch((error: any): any => {
reject(true);
return Observable.throw('Server error');
}).subscribe((envResponse :any) => {
let t = new AppConfig();
//Modify envResponse here if needed (e.g. to ajust parameters for https,...)
APP_CONFIG = Object.assign(t, envResponse);
resolve(true);
});
});
}
}
مرحله #3: در ماژول اصلی خود، این را قبل از اعلان ماژول اضافه کنید
/**
* Exported function so that it works with AOT
* @param {AppConfigService} configService
* @returns {Function}
*/
export function loadConfigService(configService: AppConfigService): Function
{
return () => { return configService.load() };
}
مرحله #۴: ارائهدهندگان ماژول را تغییر دهید تا این موارد اضافه شوند providers: [ …
AppConfigService,
{ provide: APP_INITIALIZER, useFactory: loadConfigService , deps: [AppConfigService], multi: true },
],
مرحله ۵: در کد خود، به جای استفاده از environment.configXXX، از این استفاده کنید
import {APP_CONFIG} from "../services/app-config.service";
//…
return APP_CONFIG.configXXX;
این یک مثال ساده است. در واقع، اگر از Angular Universal استفاده می کنید، باید تغییراتی ایجاد کنید، زیرا هنگام برقراری تماس های HTTP، باید از URL های مطلق استفاده کنید.
پاسخ شماره ۲
آیا از Angular-CLI استفاده میکنید؟ پس باید آسان باشد. شما چیزی شبیه به این دارید:
src/
app/
environment/
environment.ts
environment.prod.ts
به سادگی آدرس URL متفاوتی را در environment.prod.ts وارد کنید و بیلد تولید شما یک URL دوم خواهد داشت. به عنوان مثال فرض کنید environment.ts شما به این شکل است:
{
"production": false,
"apiUrl": "http://localhost:8080"
}
این را در environment.prod.ts قرار دهید:
{
"production": true,
"apiUrl": "https://example.com/api"
}
شما میتوانید محیطهای بیشتری را تنظیم کنید، آن بخش از .angular-cli.json و مخزن angular-cli را بررسی کنید.
ویرایش: طبق نظر شما، شما بیشتر میخواهید.
بله، اما هنوز هم پس از ساخت قابل تنظیم نیست، اینطور نیست؟ چون من نمیدانم کاربر چه آدرسی میخواهد استفاده کند، بنابراین میخواهم بعد از استقرار ساخت، آن را از بیرون قابل تنظیم کنم.
بیایید این سناریو را ادامه دهیم. بیایید یک کلاینت بکاند داشته باشیم:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { apiUrl } from '../environment/environment.ts';
@Injectable()
export class BackendService {
backendUrl: string = apiUrl;
constructor(private httpClient: HttpClient) {}
get(endpoint: string, params: any): Observable<any> {
const url= `${this.backendUrl}/${endpoint}`;
return this.httpClient.get(url, params);
}
}
ساده شده، اما کار میکند. به طور پیشفرض، شما URL خود را تنظیم میکنید. اما اجزای شما میتوانند URL را بهصورت پویا تنظیم کنند و چیزهای دیگر را از آن URL دریافت کنند.
حال، گام بعدی این خواهد بود که ارائه دهید کدام بکاندها را دارید. این میتواند یک آرایه از پیش پیکربندی شده باشد، یا میتوانید اجازه دهید مشتری بهطور آزاد URL را وارد کند (صرفاً جعبه ورودی). شما میتوانید یک کامپوننت داشته باشید که این کار را انجام دهد و این سرویس را در اینجا پیکربندی کند. شما احتمالاً باید یک سرویس جداگانه برای بکاند «واقعی» خود داشته باشید، جایی که مثلاً احراز هویت شما قرار دارد. اما این همه واقعاً به سناریوی شما بستگی دارد.
