【问题标题】:Including json schema files in typescript在打字稿中包含 json 模式文件
【发布时间】:2018-02-20 18:34:08
【问题描述】:

我正在使用 angular-cli 工具用 Typescript 编写一个 Angular 2 应用程序。 我有一堆我想在我的打字稿中引用的后端 API 的 JSON 模式,所以我可以将这些模式传递给模式验证器。包含 .json 文件的最佳方法是什么,以便我可以在我的打字稿中将它们作为变量引用,并在我使用 angular-cli 进行构建时将它们正确捆绑?

我的第一个想法是制作一个自定义模块并将每个模式导出为 const。我不确定这是否可能,并且无法找到有关如何引用文件的任何示例语法。

这是我现在可以使用的示例代码。唯一的问题是我必须将模式文件内容复制到我的 typercipt 中。我希望能够引用原始架构文件。

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

【问题讨论】:

    标签: angular typescript angular-cli


    【解决方案1】:

    假设您可以访问后端 API,您可以添加新的 API 点来获取 JSON 文件。然后在您的 Angular 应用程序中,您应该能够使用 HTTP Client 使用该 API 点。从中,您可以获取 JSON 文件内容并将其分配给 typescript 中的变量。

    【讨论】:

    • 感谢您的建议,这可行,但不适用于我的方案。问题是我希望能够直接在我的前端代码中引用 .json 文件内容。
    【解决方案2】:

    您不应该设置类文件以用于验证架构吗?然后,您的 Visual Studio 将在您创建时显示此类错误。

    类似的东西 出口类英雄{ 身份证号; 名称:字符串; }

    【讨论】:

      【解决方案3】:

      因为我使用 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);
      

      【讨论】:

        【解决方案4】:

        我就是这样做的。这是注册表单的示例。

        我使用@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;
        }
        

        【讨论】:

          猜你喜欢
          • 2017-05-28
          • 1970-01-01
          • 2019-04-19
          • 2018-02-06
          • 1970-01-01
          • 2017-05-13
          • 1970-01-01
          • 2016-03-05
          • 2019-01-03
          相关资源
          最近更新 更多