簡體   English   中英

在 Angular 中使用 http.get() 從本地文件加載 JSON 內容 2

[英]Load JSON content from a local file with http.get() in Angular 2

我正在嘗試使用 Angular 中的http.get()加載本地 JSON 文件 2. 我嘗試了在 Stack Overflow 上找到的一些內容。 它看起來像這樣:

這是我的app.module.ts ,我從@angular/http import HttpModuleJsonModule

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 { }

在我的組件中,我從@angular/http import HttpResponse 然后我有一個名為loadNavItems()的 function,我嘗試使用http.get()加載我的 JSON 內容,並使用console.log()打印結果。 function 在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);
    }
}

我的本地 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"
    }
]

控制台中沒有任何錯誤,我只得到這個 output:

在此處輸入圖像描述

在我的HTML 模板中,我想像這樣循環項目:

<app-nav-item-comp *ngFor="let item of navItems" [item]="item"></app-nav-item-comp>

我用我在 Stack Overflow 上找到的解決方案做了這個,但為什么它不起作用?

編輯相對路徑

我的相對路徑也有問題,但我確信當我使用../data/navItems.json時它是正確的。 在屏幕截圖中,您可以看到nav-comp.component.ts文件,我在其中使用 JSON 文件的相對路徑加載 JSON 內容,該文件位於名為數據的文件夾中? 怎么了? 控制台是否打印 404 錯誤,因為它無法從相對路徑中找到我的 JSON 文件?

在此處輸入圖像描述

對於Angular 5+,僅預成型步驟14


為了在Angular 2+ 中本地訪問您的文件,您應該執行以下操作(4 個步驟):

[1]在您的資產文件夾中創建一個.json文件,例如: data.json

[2]轉到項目中的angular.cli.json (Angular 6+ 中的 angular.json),然后在assets數組中放置另一個對象(在package.json對象之后),如下所示:

{ "glob": "data.json", "input": "./", "output": "./assets/" }

來自 angular.cli.json 的完整示例

"apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico",
        { "glob": "package.json", "input": "../", "output": "./assets/" },
        { "glob": "data.json", "input": "./", "output": "./assets/" }
      ],

請記住, data.json只是我們之前在 assets 文件夾中添加的示例文件(您可以隨意命名您的文件)

[3]嘗試通過本地主機訪問您的文件。 它應該在這個地址中可見, http://localhost:your_port/assets/data.json

如果它不可見,那么你做錯了什么。 在繼續第 4 步之前,請確保您可以通過在瀏覽器的 URL 字段中輸入它來訪問它。

[4]現在執行 GET 請求以檢索您的.json文件(您已經獲得了完整路徑.json URL,它應該很簡單)

 constructor(private http: HttpClient) {}
        // Make the HTTP request:
        this.http.get('http://localhost:port/assets/data.json')
                 .subscribe(data => console.log(data));

你必須改變

loadNavItems() {
        this.navItems = this.http.get("../data/navItems.json");
        console.log(this.navItems);
    }

為了

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.
    }

因為this.http.get返回一個Observable<Response>而你不想要響應,你想要它的內容。

console.log顯示了一個 observable,這是正確的,因為 navItems 包含一個Observable<Response>

為了在模板中正確獲取數據,您應該使用async管道。

<app-nav-item-comp *ngFor="let item of navItems | async" [item]="item"></app-nav-item-comp>

這應該工作得很好,有關更多信息,請參閱HTTP 客戶端文檔

我自己的解決方案

我在這個文件夾中創建了一個名為test的新component

在此處輸入圖片說明

我還在angular cli創建的assests文件夾中創建了一個名為test.json的模擬(重要):

在此處輸入圖片說明

這個模擬看起來像這樣:

[
        {
            "id": 1,
            "name": "Item 1"
        },
        {
            "id": 2,
            "name": "Item 2"
        },
        {
            "id": 3,
            "name": "Item 3"
        }
]

在我的組件test import的控制器中,像這樣遵循rxjs

import 'rxjs/add/operator/map'

這很重要,因為您必須從http get調用map您的response ,因此您將獲得一個json並可以在您的ngFor循環它。 這是我如何加載模擬數據的代碼。 我使用了http get並使用此路徑this.http.get("/assets/mock/test/test.json")調用了我的模擬路徑。 在此之后,我map響應並subscribe它。 然后我將它分配給我的變量items並在我的template使用ngFor循環它。 我也導出類型。 這是我的整個控制器代碼:

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

我在它的template循環:

<div *ngFor="let item of items">
  {{item.name}}
</div>

它按預期工作! 我現在可以在 assests 文件夾中添加更多模擬文件,只需更改路徑即可將其獲取為json 請注意,您還必須在控制器中導入HTTPResponse 在你 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 { }

我發現實現這一點的最簡單方法是在文件夾下添加file.jsonassets

無需編輯: .angular-cli.json

Service

@Injectable()
export class DataService {
  getJsonData(): Promise<any[]>{
    return this.http.get<any[]>('http://localhost:4200/assets/data.json').toPromise();
  }
}

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

額外的:

理想情況下,您只想在開發環境中使用它,以便防彈。 在您的environment.ts上創建一個變量

export const environment = {
  production: false,
  baseAPIUrl: 'http://localhost:4200/assets/data.json'
};

然后將http.get上的 URL 替換為${environment.baseAPIUrl}

並且environment.prod.ts可以有生產 API URL。

希望這可以幫助!

  • assets下創建/移動 json
  • 在服務中實現方法
  private URL = './assets/navItems.json'; // ./ is important!

  constructor(private httpClient: HttpClient) {
  }

  fetch(): Observable<any> {
      return this.httpClient.get(this.URL);
  }
  • 在組件中調用它
  private navItems: NavItems[];

  constructor(private navItemsService: NavItemsService) { }

  ngOnInit(): void {
    this.publicationService.fetch().subscribe(navItems => this.navItems = navItems);
  }

我想將請求的響應放在navItems 因為http.get()返回一個 observable,所以你必須訂閱它。

看這個例子:

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

將您的 navItems.json 放在“assets”文件夾中。 Angular 知道如何查看資產文件夾內部。 所以而不是:

loadNavItems() {
    this.navItems = this.http.get("../data/navItems.json");
    console.log(this.navItems);
}

將路徑更改為簡單:

    loadNavItems() {
    this.navItems = this.http.get("assets/navItems.json");
    console.log(this.navItems);
}

如果您使用的是Angular CLI: 7.3.3我所做的是,在我的資產文件夾中,我將虛假的 json 數據放在我的服務中,我只是這樣做了。

const API_URL = './assets/data/db.json';

getAllPassengers(): Observable<PassengersInt[]> {
    return this.http.get<PassengersInt[]>(API_URL);
  }

在此處輸入圖片說明

試試: this.navItems = this.http.get("data/navItems.json");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM