将检索到的数据从请求分配给模板

时间:2016-10-14 16:06:12

标签: ajax angular typescript

我正在尝试获取新闻列表,然后将其呈现在我的组件的模板中。

我正在学习本教程,该教程有点过时,http://chariotsolutions.com/blog/post/angular2-observables-http-separating-services-components/

新闻项类看起来像这样

export class NewsItemComponent {
  text: string;
  date: Date;
  author: string;
  link: string
  constructor(text: string,
              date: Date,
              author: string,
              link: string) {
    this.text = text;
    this.date = date;
    this.author = author;
    this.link = link;
  }
}

检索数据的服务:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';

import { NewsItemComponent } from './news-item/news-item.component';


@Injectable()
export class NewsService {

  constructor(public http: Http) {
    console.log('Creating NewsService');
  }

  getNews() {
    let url = 'http://localhost/test-api/';
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    this.http.post(url, '', options)
      // initial transform - result to json
      .subscribe( (res:Response) => {
        let articles: Array<any> = [];
        res.json().map((articles: Array<any>) => {

                articles.push(new NewsItemComponent('asd', new Date(), 'asdf', 'asdf'));
              });
              console.log('articles', articles);
              return articles
      });
  }
}

主要组成部分:

import { Component, OnInit, AfterViewInit, AfterViewChecked } from '@angular/core';
import { Http, Response, RequestOptions, Headers, Request, RequestMethod } from '@angular/http';
import { TranslateService } from 'ng2-translate/ng2-translate';

import { NewsItemComponent } from './news-item/news-item.component';
import { NewsService } from './news-service.service';


@Component({
  selector: 'news-section',
  templateUrl: './news-section.component.html',
  styleUrls: ['./news-section.component.scss'],
  providers: [ NewsService ]
})
export class NewsSectionComponent implements AfterViewInit {
  articles: NewsItemComponent[];

  constructor(translate: TranslateService, private http: Http, public newsService: NewsService) {
    translate.setDefaultLang('en');
    translate.use('en');

    this.articles = [];

    newsService.getNews().subscribe(res => this.articles = res);
  }



}

观点:

<section id="news" sectionVisible>
  <div>
    <h1>{{ 'Nav.News' | translate }}</h1>
  </div>
  <div class="news-wrapper clear-fix">
      <div class="column carousel-cell" ngFor="#article of articles">
        <article>
        <a href="#" class="hovered">
          <div class="bg-hover">
            <p>
              Visit
            </p>
          </div>
        </a>
        <h2>News title</h2>
        <time>21.10.2015 16:30</time>
        <p>
          Etiam faucibus sodales leo, rutrum molestie nisi luctus in. Duis quis viverra diam, vitae hendrerit augue. Donec ultricies nisi vel placerat sodales. Donec varius convallis mauris egestas vulputate. Integer fermentum tincidunt hendrerit. Donec eget nisl
          eros. Pellentesque a fringilla lorem.
        </p>
        </article>
      </div>
  </div>
</section>

当然在视图中,lorem ipsum部分将被检索到的数据更改。但是服务有问题:

newsService.getNews().subscribe(res => this.articles = res);

此行引发错误:

  

类型为void

时,属性订阅不存在

我不知道为什么会造成这种情况。 任何提示?

1 个答案:

答案 0 :(得分:1)

您需要从服务中删除subscribe方法。服务应该只返回Observables,订阅应该在实际组件中完成。

订阅Observable等于调用函数。您想要检索组件中的结果,这是您需要订阅的位置。该服务应该只保留在HTTP调用之后准备数据的逻辑(例如调用res.json())。

服务

getNews() {
  let url = 'http://localhost/test-api/';
  let headers = new Headers({ 'Content-Type': 'application/json' });
  let options = new RequestOptions({ headers: headers });

  return this.http.post(url, '', options)
     .map(res => res.json());
}

组件:

newsService.getNews()
    .subscribe( news => {
      let articles: Array<any> = [];
      news.map((articles: Array<any>) => {
            articles.push(new NewsItemComponent('asd', new Date(), 'asdf', 'asdf'));
          });
          this.articles = articles
});