我正在使用Angular 4,NPM,Node.js和Angular CLI开发一个项目。
我有一个非常不寻常的需要,在没有HTTP请求的情况下将JSON加载到Angular服务(使用@Injectable
),即它将始终作为包的一部分在本地加载,而不是从服务器检索。
到目前为止我发现的所有内容都表明您要么必须修改项目的typings.d.ts
文件,要么使用HTTP请求从/assets
文件夹或类似文件中检索它,这两个文件都不是一个选项对我来说。
我想要完成的是这个。给定以下目录结构:
/app
/services
/my-service
/my.service.ts
/myJson.json
我需要使用my.service.ts
的{{1}}服务来加载JSON文件@Injectable
。对于我的特定情况,将在myJson.json
文件旁边放置多个JSON文件,这些文件都需要加载。
澄清一下,以下方法对我不起作用:
网址:https://stackoverflow.com/a/43759870/1096637
摘录:
my.service.ts
网址:https://hackernoon.com/import-json-into-typescript-8d465beded79
摘录:
解决方案:使用通配符模块名称
在TypeScript版本2 +中,我们可以在模块名称中使用通配符。在您的TS定义文件中,例如// 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
然后,您的代码将像魅力一样工作!
declare module "*.json" {
const value: any;
export default value;
}
是否有其他人有任何想法将这些文件加载到我的服务中而不需要这些方法?
答案 0 :(得分:4)
如果直接调用json,将会出现错误,但一个简单的解决方法是为所有json文件声明打字。
typings.d.ts
declare module "*.json" {
const value: any;
export default value;
}
comp.ts
import * as data from './data.json';
答案 1 :(得分:2)
我发现的解决方案是使用RequireJS,我可以通过Angular CLI框架使用它。
我必须将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/));
}
}
答案 2 :(得分:-1)
您可以直接从构造函数中定义的对象访问服务中的变量。
...所以说你的构造函数加载像这样的服务
constructor(private someService:SomeService){}
您只需someService.theJsonObject
即可访问它。
在加载它的服务功能加载之前,请注意不要这样做。然后你会得到一个空值。
您可以像在组件文件中一样为服务文件分配变量。
只需在服务中声明它们
即可public JsonObject:any;
而且(最简单的方法)是让调用你的服务的函数为你分配JSON对象。
所以说你打电话给这样的服务
this.serviceObject.function().subscribe
(
resp =>
{
this.serviceObject.JsonObject = resp;
}
);
完成此操作后,其他组件可以使用someService.theJsonObject
访问该JSON内容,如前所述。
在您的情况下,我认为您需要做的就是在代码中嵌入JSON对象。也许你可以使用const
。这不是坏代码或任何东西。