2016-11-12 81 views
0

我想要一个名为_contextPath的变量,它是JSP中的Javascript评估变量,当前可用于systemjs.config.js - 我试图让此_contextPath变量可用在打字稿服务中。将Web应用程序上下文传递给Angular2服务

我想知道,如果_contextPath变量可以被传递到打字稿服务称为job.service.ts

这里是我的文件夹结构:

├── scripts 
│   └── mec-irs 
│    ├── app 
|  | ├── app.component.ts 
|  | ├── app.module.ts 
|  | ├── app.routes.ts 
|  | └── jobs 
|  |    ├── job.ts 
|  |    ├── job.routes.ts 
|  |     └── job.service.ts  
│    ├── db.json 
│    ├── GruntFile.js 
│    ├── index.html 
│    ├── node 
│    ├── node_modules 
│    ├── package.json 
│    ├── style.css 
│    ├── systemjs.config.js 
│    ├── tsconfig.json 
│    ├── typings 
│    └── typings.json 
├── views 
│   ├── mec.jsp 

mec.jsp获得通过JavaScript调用和存储上下文它在一个变量被称为_contextPath:

<html> 
<head> 
    <title>MEC IRS</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <script>var _contextPath = "${pageContext.request.contextPath}";</script> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="..<%=request.getContextPath()%>/scripts/mec-irs/style.css"> 

    <!-- 1. Load libraries --> 
    <!-- Polyfill(s) for older browsers --> 
    <script src="..<%=request.getContextPath()%>/scripts/mec-irs/node_modules/core-js/client/shim.min.js"></script> 
    <script src="..<%=request.getContextPath()%>/scripts/mec-irs/node_modules/zone.js/dist/zone.js"></script> 
    <script src="..<%=request.getContextPath()%>/scripts/mec-irs/node_modules/reflect-metadata/Reflect.js"></script> 
    <script src="..<%=request.getContextPath()%>/scripts/mec-irs/node_modules/systemjs/dist/system.src.js"></script> 

    <!-- 2. Configure SystemJS --> 
    <script src="..<%=request.getContextPath()%>/scripts/mec-irs/systemjs.config.js"></script> 
    <script> 
    System.import('app').catch(function(err){ console.error(err); }); 
    </script> 
</head> 

<!-- 3. Display the application --> 
<body> 
<my-app>Loading...</my-app> 
</body> 
</html> 

_contextPath用于在systemjs.config.js

/** 
* System configuration for Angular samples 
* Adjust as necessary for your application needs. 
*/ 
(function (global) { 
    System.config({ 
    paths: { 
     // paths serve as alias 
     'npm:': _contextPath + '/scripts/mec-irs/node_modules/' 
    }, 
    // map tells the System loader where to look for things 
    map: { 
     // our app is within the app folder 
     app: _contextPath + '/scripts/mec-irs/app', 
     // angular bundles 
     '@angular/core': 'npm:@angular/core/bundles/core.umd.js', 
     '@angular/common': 'npm:@angular/common/bundles/common.umd.js', 
     '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', 
     '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', 
     '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', 
     '@angular/http': 'npm:@angular/http/bundles/http.umd.js', 
     '@angular/router': 'npm:@angular/router/bundles/router.umd.js', 
     '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', 
     // other libraries 
     'rxjs':      'npm:rxjs', 
     'angular-in-memory-web-api': 'npm:angular-in-memory-web-api', 
    }, 
    // packages tells the System loader how to load when no filename and/or no extension 
    packages: { 
     app: { 
     main: './main.js', 
     defaultExtension: 'js' 
     }, 
     rxjs: { 
     defaultExtension: 'js' 
     }, 
     'angular-in-memory-web-api': { 
     main: './index.js', 
     defaultExtension: 'js' 
     } 
    } 
    }); 
})(this); 

的Java Web应用程序上下文被硬编码虽然job.service.tsmec。我想知道如何通过_contextPath这个打字稿服务job.service.ts请。由于上下文mec下面看到的是硬编码为/mec/admin/irs/jobs/,它是一个网络服务端点:

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

// Decorator to tell Angular that this class can be injected as a service to another class 
@Injectable() 
export class JobService { 

     // Class constructor with Jsonp injected 
     constructor(@Inject (Http)private http:Http) { } 

     // Base URI for Spring Batch Admin 
     private jobsUrl = '/batch/'; 

     //TODO wish not to have hardcoded context, like below 
     //private mecUrl = '/' + _contextPath + '/admin/irs/jobs/'; 
     private mecUrl = '/mec/admin/irs/jobs/'; 

     // Stop Spring Batch Job by its name 
     stopJobByName(name: string) { 
     const endPoint = name + '/stopIrsJobPoller'; 
     return this.http.get(this.mecUrl + endPoint) 
      .map(res => res.json()); 
    } 
. 
. 
.  
+0

为什么你需要这个变量? –

+0

我需要这个变量,因为在服务中,我希望通过http:// hostname/_contextPath/someRestfulWS –

回答

0

你需要的东西,这将在应用程序初始化运行,让你的服务器端的设置。这是我如何做到这一点。

创建一个类来存储你的服务器端配置:

export class AppConfig { 
    public ContextPath: string; 
}; 

创建服务,从你的JSP让您的后端配置:

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

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

@Injectable() 
export class ConfigService { 
    private _config: AppConfig; 

    constructor(private http: Http, private config: AppConfig) { 
    } 

    public Load(): Promise<AppConfig> { 
     return new Promise((resolve) => { 
      this.http.get('./views/mec.jspn').map(res=>res.json()) 
       .subscribe((config: AppConfig) => { 
        this._config = data; 
        resolve(this._config); 
       }, (error: any) => { 
        this._config = new AppConfig(); 
        resolve(this._config); 
       }); 
     }); 
    } 

    public Get(key: any): any { 
     return this._config[key]; 
    } 
} 

然后在你的应用程序模块的初始化自举其通过提供ConfigService作为APP_INITIALIZER的提供者:

import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core'; 
import { FormsModule } from '@angular/forms'; 
import { Http, HttpModule } from '@angular/http'; 
import { APP_INITIALIZER } from '@angular/core'; 

import { AppComponent } from './app.component'; 
import { AppRoutingModule } from './app-routing.module'; 
import { ConfigService } from './shared/services/index'; 
import { AppConfig } from './app.config'; 

@NgModule({ 
    declarations: [ 
     AppComponent, 
    ], 
    imports: [ 
     BrowserModule, 
     FormsModule, 
     HttpModule 
    ], 
    providers: [ 
     { 
      provide: APP_INITIALIZER, 
      useFactory: (configService: ConfigService) =>() => configService.Load(), 
      deps: [ConfigService, Http, AppConfig], 
      multi: true 
     }, 
     ConfigService, 
     AppConfig 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 

然后简单地通过在任何其他服务中注入ConfigService来使用它:

import { Http, Headers, RequestOptions, Response } from '@angular/http'; 
import { Injectable } from '@angular/core'; 

import { ConfigService } from './config.service'; 

@Injectable() 
export class AppService { 
    constructor(
     private _http: Http, 
     private _config: ConfigService 
    ) { 
     console.log(_config.Get('ContextPath')); 
    } 
} 
+0

调用Web服务我故意无法使用GET访问我的JSP,以http:// localhost:8080/mec/views/mec.jsp。即使我通过GET公开了http:// localhost:8080/mec/views/mec.jsp,您能否解释ConfigService如何确定Java Web应用程序的上下文? –

+0

我不确定你想要达到的目标。配置服务需要知道从哪里获取配置。我认为你可以通过使用this.http.get('./ views/mec.jspn')或this.http.get('http://someUrl/mec.jspn')来获取它。如果没有,你可以创建一个JSON文件存放在你的应用程序中/并使用它。另一方面,您不需要在SystemJS内设置上下文路径,只需在index.html中设置baseHref即可。 –

+0

嗨,本,你会如何在今天的Angular v4中处理这个问题?因为Angular中没有更多的APP_INITIALIZER。我可以为此目的简单地创建另一个问题,但是您的答案与我在过去3天内一直在寻找的最接近。我正在研究Rails + Angular + Shopify应用程序。我找不到一种方法来访问Response Params,特别是Angular客户端的access_token。请帮助我。谢谢。 – mayorsanmayor