【问题标题】:Angular: Is it possible to read a json file after buildingAngular:构建后是否可以读取json文件
【发布时间】:2019-07-30 09:13:42
【问题描述】:

我正在开发一个需要在不同服务器上运行的 Angular 7 项目。我需要从环境文件中读取服务器 URL 并且不能设置为静态变量。

我尝试读取 JSON 文件,但在我 ng build 项目后,它会将 JSON 的内容复制为 main.js 中的静态值

是否可以在构建项目后动态读取 JSON 文件?就像从 env.json 中读取一样,我可以在构建项目后放置

【问题讨论】:

    标签: angular


    【解决方案1】:

    我在 assets 文件夹中创建了一个 setting.json 文件,在 ng build 之后我转到 setting.json 更改后端 url。

    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
      }
    }
    

    在 app 文件夹中,我添加文件夹 configs/setting.json

    setting.json 中的内容

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

    在应用模块中添加APP_INITIALIZER

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

    【讨论】:

    • 谢谢 Hien,这个帮助了我。在下面发布我的答案
    【解决方案2】:

    在 Hien Ngyuen 的回答的帮助下,我做到了:

    添加了以下服务:

    config.service.ts

    import { Observable } from 'rxjs';
    import { map } from 'rxjs/operators';
    import { Injectable } from '@angular/core';
    import { HttpService } from './http.service';
    import { ConstantService } from './constant.service';
    
    @Injectable({
       providedIn: 'root'
    })
    export class ConfigService {
      constructor(
       private httpService: HttpService,
       private constantService: ConstantService
    ) { }
    
    /*
     *  Load configuration from env.json
     */
    loadConfig(): Observable<any> {
       let url = './assets/env.json';
    
       let requestObject = {
         API_URL: url,
         REQUEST_METHOD: this.constantService.REQUEST_METHOD_GET
       };
    
       return this.httpService.sendRequest(requestObject).pipe(map(this.extractData));
    }
    
    /*
    *  Extract data from response
    */
    private extractData(res: Response) {
       let body = res;
        return body || {};
    }
    }
    

    http.service.ts

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders } from '@angular/common/http';
    
    import { ConstantService } from './constant.service';
    
    const httpOptions = {
      withCredentials: true,
      headers: new HttpHeaders({ 'Content-Type': 'application/json' })
    };
    
    @Injectable({
      providedIn: 'root'
    })
    export class HttpService {
      constructor(
        private httpClient: HttpClient,
        private constantService: ConstantService
      ) { }
    
      sendRequest(requestData) {
        if (requestData.REQUEST_METHOD == this.constantService.REQUEST_METHOD_GET) {
          return this.httpClient.get(url, httpOptions);
        } else if (requestData.REQUEST_METHOD ==     this.constantService.REQUEST_METHOD_POST) {
          return this.httpClient.post(url, requestData.BODY, httpOptions);
        } else if (requestData.REQUEST_METHOD == this.constantService.REQUEST_METHOD_PUT) {
          return this.httpClient.put(url, requestData.BODY, httpOptions);
        } else if (requestData.REQUEST_METHOD == this.constantService.REQUEST_METHOD_DELETE) {
          return this.httpClient.delete(url, httpOptions);
        }
      }
    }
    

    接下来,在 ng build 之后,我添加了 assets\env.json,我能够更改和读取 env.json 中的值。

    【讨论】:

      【解决方案3】:

      不,我认为您必须在代码中维护一个 .json 文件,并根据您的根 url 从中动态选择。 您还可以根据请求发起的 ip 或域每次向服务器发送返回 base_url 的调用。

      {
          'server-one': 'abc.com',
          'server-two': 'abc1.com',
      }
      

      【讨论】:

        【解决方案4】:

        据我了解,您想使用 JSON 文件模拟后端请求?对我来说,最好的方法是使用拦截器,它会拦截 url。

        @Injectable()
        export class MockResponseInterceptor implements HttpInterceptor {
            constructor() { }
        
            intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
                // ignore "production" and requests to other ressources
                if (environment.production || !req.url.startsWith(environment.backendBaseUrl)) {
                    return next.handle(req);
                }
        
                const modifiedUrl: string = this.mockUrl(req.url);
                const modifiedRequest = req.clone({ url: modifiedUrl });
        
                return next.handle(modifiedRequest);
            }
        
            mockUrl(url: string): string {
              // any kind of modification or replacement etc. goes here
              // you want to return the path to the JSON file here
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-06-23
          • 2017-07-11
          • 2011-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-28
          • 1970-01-01
          相关资源
          最近更新 更多