2016-11-10 3 views
1

Ich schreibe eine Angular 2 App mit Typescript mit dem Angular-CLI-Tool. Ich habe eine Reihe von JSON-Schemas für meine Back-End-API, die ich in meinem Typoskript referenzieren möchte, damit ich diese Schemas an einen Schema-Validator übergeben kann. Was ist der beste Weg, die .json-Dateien einzuschließen, damit ich sie als Variable in meinem Typoskript referenzieren kann und sie auch richtig gebündelt habe, wenn ich einen Build mit angular-cli mache?Einschließlich JSON-Schemadateien in Typoskript

Mein erster Gedanke war, ein benutzerdefiniertes Modul zu erstellen und jedes Schema als const zu exportieren. Ich bin mir nicht sicher, ob das möglich ist und konnte keine Beispielsyntax für die Referenzierung der Dateien finden.

Hier ist mein Beispiel Code, der jetzt funktioniert. Das einzige Problem ist, dass ich den Inhalt der Schemadatei in mein Typescript kopieren musste. Ich möchte auf die ursprüngliche Schemadatei verweisen können.

import { Injectable } from "@angular/core"; 
import { Http, Response } from "@angular/http"; 

import { Observable } from "rxjs/Observable"; 
import { WlanStatus } from "./wlan-status"; 
import { JsonValidatorService } from "../../json-validator.service"; 

//import WlanStatusSchema from "../../../api/app/plugins/wifi/schemas/getStatus.json"; 
const wlanStatusSchema = 
{ 
    "type": "object", 
    "properties": { 
     "result": { 
      "type": "object", 
      "properties": { 
       "cardState": { 
        "type": "integer" 
       }, 
       "profileName": { 
        "type": "string" 
       }, 
       "clientMAC": { 
        "type": "string" 
       }, 
       "clientIP": { 
        "type": "string", 
        "format": "ipv4" 
       }, 
       "clientName": { 
        "type": "string" 
       }, 
       "AP_MAC": { 
        "type": "string" 
       }, 
       "AP_IP": { 
        "type": "string" 
       }, 
       "APName": { 
        "type": "string" 
       }, 
       "Channel": { 
        "type": "integer" 
       }, 
       "RSSI": { 
        "type": "integer" 
       }, 
       "bitRate": { 
        "type": "integer" 
       }, 
       "txPower": { 
        "type": "integer" 
       }, 
       "DTIM": { 
        "type": "integer" 
       }, 
       "beaconPeriod": { 
        "type": "integer" 
       }, 
       "SSID": { 
        "type": "string" 
       }, 
       "currentRadioMode": { 
        "type": "integer" 
       } 
      }, 
      "required": [ 
       "cardState", 
       "profileName", 
       "clientMAC", 
       "clientIP", 
       "clientName", 
       "AP_MAC", 
       "AP_IP", 
       "APName", 
       "Channel", 
       "RSSI", 
       "bitRate", 
       "txPower", 
       "DTIM", 
       "beaconPeriod", 
       "SSID", 
       "currentRadioMode" 
      ] 
     } 
    }, 
    "required": [ 
     "result" 
    ] 
}; 

@Injectable() 
export class WlanService 
{ 
    private getStatusUrl = 'app/getWlanStatus'; // URL to web API 

    constructor(private http: Http, private validator: JsonValidatorService) { } 

scan(): void 
{ 
    console.log("Scanning for APs...") 
} 

getStatus(): Observable<WlanStatus> 
{ 
    return this.issueRequest(this.getStatusUrl, wlanStatusSchema); 
} 

private issueRequest(requestUrl: string, schema: any): Observable<Object> 
{ 
    return this.http.get(requestUrl) 
     .map((res: Response) => 
     { 
      let body = res.json(); 
      let valid = this.validator.validate(schema, body.data); 
      if (!valid) 
      { 
       throw (new TypeError("Not a valid response: " + JSON.stringify(this.validator.getErrors()))); 
      } 

      return body.data.result; 
     }) 
     .catch(this.handleError); 
} 

private handleError(error: Response | any) 
{ 
    // In a real world app, we might use a remote logging infrastructure 
    let errMsg: string; 
    if (error instanceof Response) 
    { 
     const body = error.json() || ''; 
     const err = body.error || JSON.stringify(body); 
     errMsg = `${error.status} - ${error.statusText || ''} ${err}`; 
    } else 
    { 
     errMsg = error.message ? error.message : error.toString(); 
    } 
    console.error(errMsg); 
    return Observable.throw(errMsg); 
} 
} 

Antwort

0

Da ich angle-cli verwende und es webpack verwendet, konnte ich mein Problem mit der Funktion require() lösen. Webpack wird die .json-Datei ordnungsgemäß auf diese Weise bündeln.

habe ich eine Typoskript Datei alle meine Schemas zu importieren, wlan-schema.ts:

export const WlanStatusSchema = require("../../../../api/app/plugins/wifi/schemas/getStatus.json"); 

es in meinem wlan.service.ts zu verwenden:

import * as schema from "./wlan-schema"; 

this.validator.validate(schema.WlanStatusSchema, apiResp); 
0

Sollten Sie keine Klassendateien zur Validierung des Schemas einrichten? Dann wird Ihr Visual Studio solche Fehler anzeigen, wenn Sie das erstellen.

So etwas wie Exportklasse Hero { id: number; Name: Zeichenfolge; }

0

Angenommen, Sie haben Zugriff auf die Back-End-API, können Sie einen neuen API-Punkt hinzufügen, um die JSON-Datei abzurufen. Dann sollten Sie in Ihrer Angular-Anwendung diesen API-Punkt unter Verwendung von HTTP Client verwenden können. Von diesem können Sie den JSON-Dateiinhalt abrufen und einer Variablen in Typoskript zuweisen.

+0

Danke für den Rat, die für mein Szenario funktionieren würde, aber nicht. Das Problem ist, dass ich den Inhalt der JSON-Datei direkt in meinem Frontend-Code referenzieren kann. – Ryan

0

Dies ist, wie ich erledigt. Dies ist ein Beispiel für ein Registerformular.

Ich verwendete @types/json-schema für den Typ (JSONSchema4).

register.component.ts

... 
import * as registerSchema from '../../../../shared/schemas/api/create-user.json'; 
import {JSONSchema4} from 'json-schema'; 
... 
export class RegisterComponent { 
    registerSchema: JSONSchema4 = registerSchema; 
    constructor(){ 
     console.log(registerSchema.$schema); 
    } 
} 

typings.d.ts

declare module '*.json' { 
    const value: any; 
    export default value; 
}