如何将JSON数据加载到Angular2组件中

时间:2016-04-20 15:55:26

标签: json service angular

在tinterweb上运行了很多教程后,我终于开始尝试使用Angular2构建对我有用的东西,我遇到了第一个问题。我似乎无法将JSON数据加载到我的服务组件中。

我的people.json文件存储在顶层文件夹中名为data的文件夹中。

people.json

"people":[
    { age: 40, name: "Jordan Houston" },
        { age: 38, name: "Robert Eastham" },
        { age: 23, name: "Josh Beh" },
        { age: 23, name: "Joseph Canina" },
        { age: 24, name: "Alexandra Wilkins" },
        { age: 22, name: "Kiersten Costanzo" },
        { age: 23, name: "Ku Sherwood" },
        { age: 25, name: "Arta Halili" },
        { age: 24, name: "Patrick Cooney" },
        { age: 23, name: "Z.A. Perr" },
        { age: 18, name: "Tyler Mulligan" },
        { age: 26, name: "Dennis Dempsey" },
        { age: 32, name: "Francis Yeager" },
        { age: 23, name: "Phil Belardi" }
]

我相信我的问题在于friends.service.ts

friend.service.ts

import {Injectable} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';

@Injectable()

export class FriendService { 

    friends:Array<any>;

    constructor(private http:Http) 
        {
            //console.log(">>friend.service.ts:constructor--")
            http.request('./data/people.json')
                    .subscribe(response => this.friends = response.json()));
    }

        getFriends()
        {
            //console.log(">>friend.service.ts:getFriends--")
            console.log(this.friends)
            return this.friends
        }   
}

friend.service.ts在friend.component.ts

中使用

friend.component.ts

import { Component } from 'angular2/core'; 
import { FriendService } from 'app/friend.service';

@Component({
    selector: 'my-friends',
      providers: [FriendService],
        styles: [`
             div { 
                 background-color:#EFEFEF;
                 margin-bottom:15px;
                 padding:15px;
                 border:1px solid #DDD;
                 box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
                border-radius:3px;
            }
        h2 { 
            text-align: center;
        }
    `],
    template: `
        <h1>Hello from the {{ componentName }}!</h1>
        <div *ngFor="#f of friends">
            <h3>Name: {{ f.name }}</h3> 
            <h4>Age: {{ f.age }}</h4> 
        </div>
    `
})


export class FriendComponent {

    componentName: 'FriendComponent';

        constructor(private _friendService: FriendService) 
        {
        this.friends = _friendService.getFriends();
    }
} 

这生活在main.ts中

main.ts

import { Component } from 'angular2/core';
import { bootstrap } from 'angular2/platform/browser';

import { FriendComponent } from 'app/friend.component';
import {HTTP_PROVIDERS} from 'angular2/http';


@Component({
  selector: 'my-app',
    directives: [FriendComponent],
  styles: [`
  h1 {
    color:#545454;
    background:#02A8F4;
    padding:15px;
    box-shadow:2px 2px 2px 0 rgba(0, 0, 0, 0.3);
  }
  `]
  template: `
  <div>
  <h1>Hello from the {{componentName}}.</h1>
  <my-friends></my-friends>
  </div>
  `
})
export class AppComponent {
  componentName: 'AppComponent'
}

bootstrap(AppComponent,[HTTP_PROVIDERS])

...这里是索引页面......

<!DOCTYPE html>
<html>
<head>
  <script>document.write('<base href="' + document.location + '" />');</script>

  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!--Add Bootstrap CSS Styles-->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">

  <!-- IE required polyfills, in this exact order -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.1/es6-shim.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
  <script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

  <!-- Angular polyfill required everywhere -->
  <script src="https://code.angularjs.org/2.0.0-beta.8/angular2-polyfills.js"></script>

  <script src="https://code.angularjs.org/tools/system.js"></script>
  <script src="https://code.angularjs.org/tools/typescript.js"></script>
  <script src="https://code.angularjs.org/2.0.0-beta.8/Rx.js"></script>
  <script src="https://code.angularjs.org/2.0.0-beta.8/angular2.dev.js"></script>
  <script src="https://code.angularjs.org/2.0.0-beta.8/router.dev.js"></script>
  <script src="https://code.angularjs.org/2.0.0-beta.8/http.dev.js"></script>

  <script>
      System.config({
        transpiler: 'typescript', 
        typescriptOptions: { emitDecoratorMetadata: true }, 
        packages: {
          'api': {defaultExtension: 'ts'}, 
          'app': {defaultExtension: 'ts'} 
        } 
      });
    System.import('app/main')
          .then(null, console.error.bind(console));
  </script>

</head>
<body class="container">

  <my-app>Loading...</my-app>

</body>
</html>

非常感谢任何帮助;)

1 个答案:

答案 0 :(得分:14)

实际上,这是因为您的数据是异步加载的。因此,在组件的构造函数中,您最初会得到一个未定义的值。

constructor(private _friendService: FriendService) {
  this.friends = _friendService.getFriends();
}

要保持这样的构造函数,您需要重构代码以使服务的getFriends方法返回一个可观察的:

@Injectable()
export class FriendService { 
  constructor(private http:Http) {
  }

  getFriends() {
    return this.http.request('./data/people.json')
                 .map(res => res.json());
  }
}

然后,您可以将async管道用于组件模板:

template: `
    <h1>Hello from the {{ componentName }}!</h1>
    <div *ngFor="#f of friends | async">
        <h3>Name: {{ f.name }}</h3> 
        <h4>Age: {{ f.age }}</h4> 
    </div>
`