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

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

问题描述

我正在使用Angular 4,NPM,Node.js和Angular CLI进行项目.

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

到目前为止,我发现的所有内容都表明您要么必须修改项目的typings.d.ts文件,要么使用HTTP请求从/assets文件夹或类似文件中检索它,这两个选项都不是我的选择. /p>

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

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

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

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

使用HTTP服务从资产中加载JSON文件

URL: 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);

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

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

节选:

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

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

然后,您的代码将像魅力一样工作!

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

问题

是否有人需要将这些文件加载​​到我的服务中而无需使用任何一种方法?

解决方案

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

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

declare var require: any;

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

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

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

示例结果从文件夹../types加载文件type1.jsontype2.jsontype3.json:

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

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

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.

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

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:

Using an HTTP Service to Load JSON File From Assets

URL: https://stackoverflow.com/a/43759870/1096637

Excerpt:

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

Modifying typings.d.ts To Allow Loading JSON Files

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

Excerpt:

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?

解决方案

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

I had to declare require as a variable globally:

declare var require: any;

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.

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.

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.

Example Result loading files type1.json, type2.json, and type3.json from the folder ../types:

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

The Final Service File

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天全站免登陆