Javascript 使用 angular 2 中的 http.get() 从本地文件加载 json
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44042223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Load json from local file with http.get() in angular 2
提问by webta.st.ic
I'm trying to load a local json with http.get()in angular 2. I tried something, that I found here on stack. It looks like this:
我正在尝试使用http.get()angular 2加载本地 json 。我尝试了一些东西,我在堆栈中找到了这些东西。它看起来像这样:
this is my app.module.tswhere I importthe HttpModuleand the JsonModulefrom @angular/http:
这是我的app.module.ts,我import的HttpModule和JsonModule来自@angular/http:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { NavCompComponent } from './nav-comp/nav-comp.component';
import { NavItemCompComponent } from './nav-comp/nav-item-comp/nav-item-comp.component';
@NgModule({
declarations: [
AppComponent,
NavCompComponent,
NavItemCompComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
JsonpModule,
RouterModule.forRoot(appRoutes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
In my componentI importHttpand Responsefrom @angular/http. Then I have a function called loadNavItems(), where I try to load my json with relative path using http.get()and print the result with console.log(). The function is called in ngOnInit():
在我的组件中IimportHttp和Response来自@angular/http. 然后,我有调用的函数loadNavItems(),在这里我尝试使用加载的json使用相对路径http.get(),并打印其结果console.log()。该函数被调用ngOnInit():
import { Component, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
@Component({
selector: 'app-nav-comp',
templateUrl: './nav-comp.component.html',
styleUrls: ['./nav-comp.component.scss']
})
export class NavCompComponent implements OnInit {
navItems: any;
constructor(private http: Http) { }
ngOnInit() {
this.loadNavItems();
}
loadNavItems() {
this.navItems = this.http.get("../data/navItems.json");
console.log(this.navItems);
}
}
My local json filelooks like this:
我的本地 json 文件如下所示:
[{
"id": 1,
"name": "Home",
"routerLink": "/home-comp"
},
{
"id": 2,
"name": "Über uns",
"routerLink": "/about-us-comp"
},
{
"id": 3,
"name": "Events",
"routerLink": "/events-comp"
},
{
"id": 4,
"name": "Galerie",
"routerLink": "/galery-comp"
},
{
"id": 5,
"name": "Sponsoren",
"routerLink": "/sponsoring-comp"
},
{
"id": 6,
"name": "Kontakt",
"routerLink": "/contact-comp"
}
]
There are no errors in the console, I just get this output:
In my html templateI would like to loop the items like this:
在我的html 模板中,我想循环这样的项目:
<app-nav-item-comp *ngFor="let item of navItems" [item]="item"></app-nav-item-comp>
I made this with a solution I found here on stack, but I have no idea why it doesn't work?
我用我在堆栈上找到的解决方案做了这个,但我不知道为什么它不起作用?
EDIT RELATIVE PATH:I also get a problem with my relative path, but I'm sure it's the right one when I use ../data/navItems.json. In the screenshot you can se the nav-comp.component.ts, where I load the json using relative path from the json file which is in the folder called data? What's wrong, the console prints an 404 error, because it can't find my json file from the relative path?
编辑相对路径:我的相对路径也有问题,但我确信当我使用../data/navItems.json. 在屏幕截图中,您可以设置 nav-comp.component.ts,我使用来自名为 data 的文件夹中的 json 文件的相对路径加载 json?怎么了,控制台打印404错误,因为从相对路径找不到我的json文件?
采纳答案by webta.st.ic
MY OWN SOLUTION
我自己的解决方案
I created a new componentcalled testin this folder:
我在这个文件夹中创建了一个新的component调用test:
I also created a mock called test.jsonin the assestsfolder created by angular cli(important):
我还创建了一个test.json在(重要)assests创建的文件夹中调用的模拟angular cli:
This mock looks like this:
这个模拟看起来像这样:
[
{
"id": 1,
"name": "Item 1"
},
{
"id": 2,
"name": "Item 2"
},
{
"id": 3,
"name": "Item 3"
}
]
In the controller of my component testimportfollow rxjslike this
在我的组件的控制器testimport如下rxjs这样
import 'rxjs/add/operator/map'
This is important, because you have to mapyour responsefrom the http getcall, so you get a jsonand can loop it in your ngFor. Here is my code how I load the mock data. I used httpgetand called my path to the mock with this path this.http.get("/assets/mock/test/test.json"). After this i mapthe response and subscribeit. Then I assign it to my variable itemsand loop it with ngForin my template. I also export the type. Here is my whole controller code:
这一点很重要,因为你要map你response从http get电话,所以你得到一个json在你的和可循环它ngFor。这是我如何加载模拟数据的代码。我使用httpget并使用此路径调用了我的模拟路径this.http.get("/assets/mock/test/test.json")。在这之后我map的回应和subscribe它。然后我将它分配给我的变量items并ngFor在我的template. 我也导出类型。这是我的整个控制器代码:
import { Component, OnInit } from "@angular/core";
import { Http, Response } from "@angular/http";
import 'rxjs/add/operator/map'
export type Item = { id: number, name: string };
@Component({
selector: "test",
templateUrl: "./test.component.html",
styleUrls: ["./test.component.scss"]
})
export class TestComponent implements OnInit {
items: Array<Item>;
constructor(private http: Http) {}
ngOnInit() {
this.http
.get("/assets/mock/test/test.json")
.map(data => data.json() as Array<Item>)
.subscribe(data => {
this.items = data;
console.log(data);
});
}
}
And my loop in it's template:
我的循环是template:
<div *ngFor="let item of items">
{{item.name}}
</div>
It works as expected! I can now add more mock files in the assests folder and just change the path to get it as json. Notice that you have also to import the HTTPand Responsein your controller. The same in you app.module.ts (main) like this:
它按预期工作!我现在可以在assests文件夹中添加更多模拟文件,只需更改路径即可将其作为json. 请注意,您还必须在控制器中导入HTTP和Response。在你 app.module.ts (main) 中同样如此:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { TestComponent } from './components/molecules/test/test.component';
@NgModule({
declarations: [
AppComponent,
TestComponent
],
imports: [
BrowserModule,
HttpModule,
JsonpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
回答by Eugen Sunic
For Angular 5+only preform steps 1and 4
对于Angular 5+,仅预成型步骤1和4
In order to access your file locally in Angular 2+you should do the following (4 steps):
为了在Angular 2+ 中本地访问您的文件,您应该执行以下操作(4 个步骤):
[1]Inside your assets folder create a .jsonfile, example: data.json
[1]在您的资产文件夹中创建一个.json文件,例如:data.json
[2]Go to your angular.cli.json(angular.json in Angular 6+) inside your project and inside the assetsarray put another object (after the package.jsonobject) like this:
[2]转到项目中的angular.cli.json(Angular 6+ 中的 angular.json),然后在assets数组中放置另一个对象(在package.json对象之后),如下所示:
{ "glob": "data.json", "input": "./", "output": "./assets/" }
{ "glob": "data.json", "input": "./", "output": "./assets/" }
full example from angular.cli.json
来自 angular.cli.json 的完整示例
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico",
{ "glob": "package.json", "input": "../", "output": "./assets/" },
{ "glob": "data.json", "input": "./", "output": "./assets/" }
],
Remember, data.jsonis just the example file we've previously added in the assets folder (you can name your file whatever you want to)
请记住,data.json只是我们之前在 assets 文件夹中添加的示例文件(您可以随意命名您的文件)
[3]Try to access your file via localhost. It should be visible within this address, http://localhost:your_port/assets/data.json
[3]尝试通过本地主机访问您的文件。它应该在这个地址中可见,http://localhost:your_port/assets/data.json
If it's not visiblethen you've done something incorrectly. Make sure you can access it by typing it in the URL field in your browser before proceeding to step #4.
如果它不可见,那么你做错了什么。在继续第 4 步之前,请确保您可以通过在浏览器的 URL 字段中输入它来访问它。
[4]Now preform a GET request to retrieve your .jsonfile (you've got your full path .jsonURL and it should be simple)
[4]现在执行 GET 请求以检索您的.json文件(您已经获得了完整路径.jsonURL,它应该很简单)
constructor(private http: HttpClient) {}
// Make the HTTP request:
this.http.get('http://localhost:port/assets/data.json')
.subscribe(data => console.log(data));
回答by Supamiu
You have to change
你必须改变
loadNavItems() {
this.navItems = this.http.get("../data/navItems.json");
console.log(this.navItems);
}
for
为了
loadNavItems() {
this.navItems = this.http.get("../data/navItems.json")
.map(res => res.json())
.do(data => console.log(data));
//This is optional, you can remove the last line
// if you don't want to log loaded json in
// console.
}
Because this.http.getreturns an Observable<Response>and you don't want the response, you want its content.
因为this.http.get返回 anObservable<Response>而您不想要响应,所以您想要它的内容。
The console.logshows you an observable, which is correct because navItems contains an Observable<Response>.
在console.log你展示了一个可观察到的,这是正确的,因为navItems包含Observable<Response>。
In order to get data properly in your template, you should use asyncpipe.
为了在模板中正确获取数据,您应该使用async管道。
<app-nav-item-comp *ngFor="let item of navItems | async" [item]="item"></app-nav-item-comp>
This should work well, for more informations, please refer to HTTP Client documentation
这应该工作得很好,有关更多信息,请参阅HTTP 客户端文档
回答by T04435
I found that the simplestway to achieve this is by adding the file.jsonunder folder: assets.
我发现实现这一点的最简单方法是在文件夹下添加file.json:assets。
No need to edit:.angular-cli.json
无需编辑:.angular-cli.json
Service
Service
@Injectable()
export class DataService {
getJsonData(): Promise<any[]>{
return this.http.get<any[]>('http://localhost:4200/assets/data.json').toPromise();
}
}
Component
Component
private data: any[];
constructor(private dataService: DataService) {}
ngOnInit() {
data = [];
this.dataService.getJsonData()
.then( result => {
console.log('ALL Data: ', result);
data = result;
})
.catch( error => {
console.log('Error Getting Data: ', error);
});
}
Extra:
额外的:
Ideally, you only want to have this in a dev environment so to be bulletproof. create a variable on your environment.ts
理想情况下,您只想在开发环境中使用它,以便防弹。在你的上创建一个变量environment.ts
export const environment = {
production: false,
baseAPIUrl: 'http://localhost:4200/assets/data.json'
};
Then replace the URL on the http.getfor ${environment.baseAPIUrl}
然后将http.get上的 URL 替换为${environment.baseAPIUrl}
And the environment.prod.tscan have the production API URL.
并且environment.prod.ts可以具有生产 API URL。
Hope this helps!
希望这可以帮助!
回答by runit
I you want to put the response of the request in the navItems. Because http.get()return an observable you will have to subscribe to it.
我想把请求的响应放在navItems. 因为http.get()返回一个 observable 你必须订阅它。
Look at this example:
看这个例子:
// version without map
this.http.get("../data/navItems.json")
.subscribe((success) => {
this.navItems = success.json();
});
// with map
import 'rxjs/add/operator/map'
this.http.get("../data/navItems.json")
.map((data) => {
return data.json();
})
.subscribe((success) => {
this.navItems = success;
});
回答by aRtoo
If you are using Angular CLI: 7.3.3What I did is, On my assets folder I put my fake json data then on my services I just did this.
如果您使用的Angular CLI: 7.3.3是我所做的是,在我的资产文件夹中,我将我的假 json 数据放在我的服务中,我只是这样做了。
const API_URL = './assets/data/db.json';
const API_URL = './assets/data/db.json';
getAllPassengers(): Observable<PassengersInt[]> {
return this.http.get<PassengersInt[]>(API_URL);
}
回答by Miodrag Maric
try:
this.navItems = this.http.get("data/navItems.json");
尝试:
this.navItems = this.http.get("data/navItems.json");

