Загрузка JSON без HTTP-запроса



Я работаю над проектом, используя Angular 4, NPM, Node.js и угловой CLI.



У меня есть довольно необычная потребность загрузить JSON в угловой сервис (используя @Injectable) без HTTP-запроса, то есть он всегда будет загружен локально как часть пакета, а не извлекаться с сервера.

Все, что я нашел до сих пор, указывает на то, что вам нужно либо изменить файл проекта typings.d.ts, либо использовать HTTP-запрос для его извлечения из папки /assets или аналогичного, ни один из что для меня тоже вариант.



То, что я пытаюсь выполнить это. Дана следующая структура каталогов:



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


Мне нужна служба my.service.ts, которая использует @Injectable, чтобы загрузить файл JSON myJson.json. В моем конкретном случае рядом с файлом my.service.ts будет находиться несколько файлов JSON, которые все должны быть загружены.



Чтобы прояснить, следующие подходы не будут работать для меня:



Использование службы HTTP для загрузки файла JSON из Assets



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


Изменение типов.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'


Вопрос



Есть ли у кого-нибудь еще идеи по загрузке этих файлов в мой сервис без необходимости использования любого из этих подходов?

661   3  

3 ответов:

Вы получите ошибку, если вызовете json напрямую, но простой обходной путь заключается в объявлении типов для всех файлов json.

машинопись.d. ts

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

комп.ts

import * as data from './data.json';

Решение, которое я нашел для этого, было с помощью RequireJS, который был доступен мне через Angular CLI framework.

Я должен был объявить require как переменную глобально:

declare var require: any;

И затем я мог бы использовать require.context, чтобы получить все файлы в папке, которую я создал для хранения типов в ../types.

Пожалуйста, найдите ниже всю завершенную службу, которая загружает все файлы JSON (каждый из которых является типом) в служебную переменную types.

Результатом является объект типы, где ключом для типа является имя файла, а связанным значением-JSON из файла.

Пример результата загрузки файлов type1.json, type2.json, и type3.json из папки ../types:

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

Вы можете напрямую обращаться к переменным в службах из их объекта, определенного в конструкторе.

... Итак, скажем, ваш конструктор загружает службу следующим образом

constructor(private someService:SomeService){}

Вы можете просто сделать someService.theJsonObject, чтобы получить к нему доступ.

Просто будьте осторожны, чтобы не сделать этого до того, как он будет загружен служебной функцией, которая его загружает. Тогда вы получите нулевое значение.

Вы можете назначать переменные вашим служебным файлам так же, как и в файлах компонентов.

Просто объявите их в служба

public JsonObject:any;

И (самый простой способ) - позволить функции, вызвавшей ваш сервис, назначить вам объект JSON.

Итак, скажем, вы назвали службу так

this.serviceObject.function().subscribe
(
  resp =>
  {
    this.serviceObject.JsonObject = resp;
  }
);

После того, как это сделано один раз, другие компоненты могут получить доступ к содержимому JSON, используя someService.theJsonObject, Как обсуждалось ранее.


В вашем случае, я думаю, все, что вам нужно сделать, это встроить объект JSON в ваш код. Может быть, вы можете использовать const. Это неплохой код или что-то в этом роде.

Comments

    Ничего не найдено.