在打字稿中包含 json 模式文件
Including json schema files in typescript
我正在使用 angular-cli 工具使用 Typescript 编写一个 Angular 2 应用程序。
我的后端 API 有一堆 JSON 模式,我想在打字稿中引用它们,这样我就可以将这些模式传递给模式验证器。包含 .json 文件的最佳方法是什么,这样我就可以在打字稿中将它们作为变量引用,并在使用 angular-cli 进行构建时将它们正确捆绑?
我的第一个想法是制作一个自定义模块并将每个模式导出为常量。我不确定这是否可行,并且无法找到有关如何引用文件的任何示例语法。
这是我现在可以使用的示例代码。唯一的问题是我必须将模式文件内容复制到我的 typesrcipt 中。我希望能够引用原始架构文件。
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);
}
}
您不应该设置 class 文件来验证架构吗?然后你的 visual studio 会在你创建时显示这样的错误。
有点像
导出 class 英雄 {
身份证号;
名称:字符串;
}
假设您可以访问后端 API,您可以添加新的 API 点来获取 JSON 文件。然后在您的 Angular 应用程序中,您应该能够使用 HTTP Client 消耗那个 API 积分。从那里,您可以获得 JSON 文件内容并将其分配给打字稿中的变量。
因为我正在使用 angular-cli 并且它使用了 webpack,所以我能够通过使用 require() 函数来解决我的问题。 Webpack 将以这种方式正确地捆绑 .json 文件。
我创建了一个打字稿文件来导入我所有的模式,wlan-schema.ts:
export const WlanStatusSchema = require("../../../../api/app/plugins/wifi/schemas/getStatus.json");
在我的wlan.service.ts中使用它:
import * as schema from "./wlan-schema";
this.validator.validate(schema.WlanStatusSchema, apiResp);
我就是这样做的。这是注册表单的示例。
我使用 @types/json-schema 作为类型 (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;
}
我正在使用 angular-cli 工具使用 Typescript 编写一个 Angular 2 应用程序。 我的后端 API 有一堆 JSON 模式,我想在打字稿中引用它们,这样我就可以将这些模式传递给模式验证器。包含 .json 文件的最佳方法是什么,这样我就可以在打字稿中将它们作为变量引用,并在使用 angular-cli 进行构建时将它们正确捆绑?
我的第一个想法是制作一个自定义模块并将每个模式导出为常量。我不确定这是否可行,并且无法找到有关如何引用文件的任何示例语法。
这是我现在可以使用的示例代码。唯一的问题是我必须将模式文件内容复制到我的 typesrcipt 中。我希望能够引用原始架构文件。
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);
}
}
您不应该设置 class 文件来验证架构吗?然后你的 visual studio 会在你创建时显示这样的错误。
有点像 导出 class 英雄 { 身份证号; 名称:字符串; }
假设您可以访问后端 API,您可以添加新的 API 点来获取 JSON 文件。然后在您的 Angular 应用程序中,您应该能够使用 HTTP Client 消耗那个 API 积分。从那里,您可以获得 JSON 文件内容并将其分配给打字稿中的变量。
因为我正在使用 angular-cli 并且它使用了 webpack,所以我能够通过使用 require() 函数来解决我的问题。 Webpack 将以这种方式正确地捆绑 .json 文件。
我创建了一个打字稿文件来导入我所有的模式,wlan-schema.ts:
export const WlanStatusSchema = require("../../../../api/app/plugins/wifi/schemas/getStatus.json");
在我的wlan.service.ts中使用它:
import * as schema from "./wlan-schema";
this.validator.validate(schema.WlanStatusSchema, apiResp);
我就是这样做的。这是注册表单的示例。
我使用 @types/json-schema 作为类型 (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;
}