在没有 HTTP 请求的情况下加载 JSON [英] Loading JSON Without an HTTP Request

查看:26
本文介绍了在没有 HTTP 请求的情况下加载 JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Angular 4、NPM、Node.js 和 Angular CLI 开展一个项目.

I am working on a project using Angular 4, NPM, Node.js, and the Angular CLI.

我需要在没有 HTTP 请求的情况下将 JSON 加载到 Angular 服务中(使用 @Injectable),即它总是作为包的一部分在本地加载,而不是检索来自服务器.

I have a rather unusual need to load JSON into an Angular service (using an @Injectable) without an HTTP request, i.e. it will always be loaded locally as part of the package, and not retrieved from a server.

到目前为止我发现的一切都表明您必须修改项目的 typings.d.ts 文件或使用 HTTP 请求从 /assets 中检索它> 文件夹或类似文件夹,这两个都不适合我.

Everything I've found so far indicates that you either have to modify the project's typings.d.ts file or use an HTTP request to retrieve it from the /assets folder or similar, neither of which is an option for me.

我想要完成的是这个.给定以下目录结构:

What I am trying to accomplish is this. Given the following directory structure:

/app
    /services
        /my-service
            /my.service.ts
            /myJson.json

我需要使用 @Injectablemy.service.ts 服务来加载 JSON 文件 myJson.json.对于我的特殊情况,my.service.ts 文件旁边将有多个 JSON 文件,这些文件都需要加载.

I need the my.service.ts service, which is using @Injectable, to load the JSON file myJson.json. For my particular case, there will be multiple JSON files sitting next to the my.service.ts file that will all need to be loaded.

澄清一下,以下方法对我不起作用:

To clarify, the following approaches will not work for me:

网址:https://stackoverflow.com/a/43759870/1096637

摘录:

// Get users from the API
return this.http.get('assets/ordersummary.json')//, options)
    .map((response: Response) => {
        console.log("mock data" + response.json());
        return response.json();
    }
    )
    .catch(this.handleError);

修改typings.d.ts 以允许加载JSON 文件

网址:https://hackernoon.com/import-json-into-typescript-8d465beded79

摘录:

解决方案:使用通配符模块名称在 TypeScript 2+ 版本中,我们可以在模块名称中使用通配符.在您的 TS 定义文件中,例如typings.d.ts,你可以添加这一行:

Solution: Using Wildcard Module Name In TypeScript version 2 +, we can use wildcard character in module name. In your TS definition file, e.g. typings.d.ts, you can add this line:

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

然后,您的代码就会很有魅力!

Then, your code will work like charm!

// TypeScript
// app.ts
import * as data from './example.json';
const word = (<any>data).name;
console.log(word); // output 'testing'

问题

有没有其他人有任何想法可以将这些文件加载​​到我的服务中,而无需这些方法中的任何一种?

The Question

Does anyone else have any ideas for getting these files loaded into my service without the need for either of these approaches?

推荐答案

我找到的解决方案是使用 RequireJS,我可以通过 Angular CLI 框架使用它.

The solution I found to this was using RequireJS, which was available to me via the Angular CLI framework.

我必须将 require 声明为全局变量:

I had to declare require as a variable globally:

declare var require: any;

然后我可以使用 require.context 来获取我创建的文件夹中的所有文件,以保存 ../types 中的类型.

And then I could use require.context to get all of the files in a folder I created to hold on the types at ../types.

请在下面找到将所有 JSON 文件(每个文件都是一个类型)加载到服务变量 types 中的完整服务.

Please find below the entire completed service that loads all of the JSON files (each of which is a type) into the service variable types.

结果是一个类型的对象,其中类型的键是文件名,相关值是来自文件的 JSON.

The result is an object of types, where the key for the type is the file name, and the related value is the JSON from the file.

{
    type1: {
        class: "myClass1",
        property1: "myProperty1"
    },
    type2: {
        class: "myClass2",
        property1: "myProperty2"
    },
    type3: {
        class: "myClass3",
        property1: "myProperty3"
    }
}

最终服务文件

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

declare var require: any;

@Injectable()
export class TypeService {

    constructor(){
        this.init()
    };

    types: any;

    init: Function = () => {

        // Get all of the types of branding available in the types folder
        this.types = (context => {

            // Get the keys from the context returned by require
            let keys = context.keys();

            // Get the values from the context using the keys
            let values = keys.map(context);

            // Reduce the keys array to create the types object
            return keys.reduce(
                (types, key, i) => {

                    // Update the key name by removing "./" from the begining and ".json" from the end.
                    key = key.replace(/^\.\/([^\.]+)\.json/, (a, b)=> { return b; });

                    // Set the object to the types array using the new key and the value at the current index
                    types[key] = values[i].data; 

                    // Return the new types array
                    return types; 
                }, {}
            );
        })(require.context('../types', true, /.json/));
    }
}

这篇关于在没有 HTTP 请求的情况下加载 JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆