使用角度为2

时间:2017-05-18 08:17:05

标签: javascript html json angular http

我正在尝试使用角度为2的http.get()加载一个本地json。我尝试了一些东西,我在堆栈中找到了这个东西。它看起来像这样:

这是我的app.module.tsimport HttpModuleJsonModule来自@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 { }

在我的组件import HttpResponse来自@angular/http。然后我有一个名为loadNavItems()的函数,我尝试使用http.get()加载带有相对路径的json,并使用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);
    }
}

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

控制台中没有错误,我只是得到了这个输出:enter image description here

在我的 html模板中,我想循环这样的项目:

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

我用堆栈中找到的解决方案制作了这个,但我不知道它为什么不起作用?

编辑相对路径: 我的相对路径也遇到问题,但我确定使用../data/navItems.json时它是正确的。在屏幕截图中你可以看到nav-comp.component.ts,在那里我使用json文件中的相对路径加载json,该文件位于名为data的文件夹中?怎么了,控制台打印出404错误,因为它无法从相对路径找到我的json文件?

enter image description here

9 个答案:

答案 0 :(得分:59)

修改

Angular 5 + 仅执行 1 4

步骤

要在 Angular 2 + 中本地访问您的文件,您应该执行以下操作(4个步骤):

[1] 在您的资源文件夹中创建 .json 文件,例如: data.json

[2] 转到项目内的 angular.cli.json (Angular 6+中的angular.json)和资产数组放置另一个对象(在 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] 尝试通过localhost访问您的文件。它应该在此地址http://localhost:your_port/assets/data.json

中可见

如果不可见而不是你做错了什么。在继续执行步骤#4之前,请确保您可以在浏览器的URL字段中键入它来访问它。

[4] 现在预先形成GET请求以检索 .json 文件(您已获得完整路径 .json 网址和它应该很简单)

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

答案 1 :(得分:12)

你必须改变

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 pipe。

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

这应该效果很好,有关更多信息,请参阅HTTP Client documentation

答案 2 :(得分:8)

我自己的解决方案

我在此文件夹中创建了一个名为component的新test

enter image description here

我还在test.json创建的assests文件夹中创建了一个名为angular cli的模拟器(重要):

enter image description here

这个模拟看起来像这样:

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

在我的组件test import的控制器中,按照rxjs这样关注

import 'rxjs/add/operator/map'

这一点非常重要,因为您必须map来自response来自http get json,因此您获得ngFor并可以在http中循环播放get }。这是我的代码如何加载模拟数据。我使用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); }); } } 中将其与template一起循环。我也导出类型。这是我的整个控制器代码:

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

我的循环是json

HTTP

按预期工作!我现在可以在assests文件夹中添加更多模拟文件,只需更改路径即可将其作为Response。请注意,您还必须在控制器中导入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 { } $num = 0; for ($i=1;$i<=66;$i++){ print_r($days[$num]); $num = ($num ==5) ? 0 : num +1; } 。 app.module.ts(main)就像这样:

StringRequest stringRequest = new StringRequest("https://restcountries.eu/data/ata.svg",new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    SVG svg = SVG.getFromString(response);

                    ImageView ig_countries_ = (ImageView) findViewById(R.id.ig1);
                    Glide.with(getApplicationContext()).load(svg).into(ig_countries_);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
            }
        });
        RequestQueue queue = Volley.newRequestQueue(this);
        stringRequest.setShouldCache(true);
        queue.add(stringRequest);

答案 3 :(得分:4)

我发现 最简单 实现此目的的方法是在文件夹下添加 file.json assets

无需修改: .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 上的网址替换为 ${environment.baseAPIUrl}

environment.prod.ts可以拥有生产API网址。

希望这有帮助!

答案 4 :(得分:1)

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

答案 5 :(得分:0)

我想将请求的响应放在navItems中。因为http.get()返回一个可观察的,你将不得不订阅它。

看看这个例子:

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

答案 6 :(得分:0)

将您的 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);
}

答案 7 :(得分:-1)

如果您使用的是Angular CLI: 7.3.3,则是在我的资产文件夹中放置了伪造的json数据,然后将其放置在服务中。

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

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

enter image description here

答案 8 :(得分:-3)

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