2016-04-20 4 views
7

После запуска многих обучающих программ на tinterweb я, наконец, начал пытаться создать что-то полезное для меня, используя Angular2, и я столкнулся с первой проблемой. Я не могу загрузить данные JSON в свой сервисный компонент.Как загрузить данные JSON в компонент Angular2

файл my 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 используется в the 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> 

Любая помощь будет значительно оценивается;)

ответ

14

Фактически, это потому, что ваши данные загружаются asynch ronously. Таким образом, внутри конструктора вашего компонента вы сначала получаете неопределенное значение.

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> 
` 
+0

Привет Тьерри Благодаря реагирования на быстро. Я уже пробовал использовать карту, но я получаю сообщение об ошибке в консоли ... TypeError: this.http.request (...). Map не является функцией В результате, это еще не рендеринг. .. – Beaker

+2

Вы радушны! Вам нужно импортировать оператора. См. Этот вопрос: http://stackoverflow.com/questions/34515173/angular-2-http-get-with-typescript-error-http-get-map-is-not-a-function-in/34515276#34515276. –

+0

Комментарий к вопросу о том, что делать для ошибок, связанных с .map, должен быть добавлен к основному ответу, это было для меня тоже, возможно, для других. –