【问题标题】:How to display results after fetching JSON from external source in Angular2如何在Angular2中从外部源获取JSON后显示结果
【发布时间】:2017-07-05 16:44:08
【问题描述】:

我正在使用 omdbapi.com API 制作一个简单的电影数据搜索引擎。我已经设置了服务来获取数据和组件来创建视图,但是当我尝试连接到 HTML 时出现错误:

找不到“object”类型的不同支持对象“[object Object]”。 NgFor 仅支持绑定到 Iterables,例如 Arrays。 错误:找不到“object”类型的不同支持对象“[object Object]”。 NgFor 只支持绑定到 Arrays 等 Iterables。

电影课

export class Movie {
    constructor(
        Title: string,
        Year: string,
        Rated: string,
        Released: string,
        Runtime: string,
        Genre: string,
        Director: string,
        Writer: string,
        Actors: string,
        Plot: string,
        Language: string,
        Country: string,
        Awards: string,
        Poster: string,
        Metascore: string,
        imdbRating: string,
        imdbVotes: string,
        imdbID: string,
        Type: string,
        Response: string
    ) {}

}

这是我的组件:

import { Component, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

//observable class extensions
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
//observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';

import { MovieSearchService } from './movie-search.service';
import { Movie } from './movie';

@Component({
    selector: 'movie-search',
    templateUrl: './movie-search.component.html',
    styleUrls: ['./movie-search.component.css'],
    providers: [MovieSearchService]
})

export class MovieSearchComponent implements OnInit {
    movies: Observable<Movie[]>;
    private searchTerms = new Subject<string>();

    constructor(
        private movieSearchService: MovieSearchService,
        private http: Http
    ) {}

    search(term:string) {
        return this.searchTerms.next(term);
    }

    ngOnInit(): void {
      this.movies = this.searchTerms
        .debounceTime(300) // wait 300ms after each keystroke before considering the term
        .distinctUntilChanged() // ignore if next search term is same as previous
        .switchMap(term => term // switch to new observable each time the term changes
        // return the http search observable
        ? this.movieSearchService.search(term)
            // or the observable of empty heroes if there was no search term
        : Observable.of<Movie[]>([])
        )
        .catch(error => {
            console.log("--------- Error -------");
            console.log( error );

            return Observable.of<Movie[]>([]);
        })     
    }
}

这是服务

import { Injectable } from '@angular/core';
import { Http, Jsonp } from '@angular/http';

import { Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { Movie } from './movie';

@Injectable()
export class MovieSearchService {
    constructor(
        private http: Http,
        private jsonp: Jsonp
    ) {}

    search(term: string): Observable<Movie[]> {
        return this.http
            .get(`http://www.omdbapi.com/?s=${term}`)
            .map(response => {
                return response.json().each() as Movie[]
            })
    }
}

还有风景

<div class="col-xs-12">
   <input #searchBox id="search-box" />
   <button (click)="search(searchBox.value)">Search</button>
</div>

<ul *ngIf="movies">
    <li *ngFor="let movie of movies">
        {{ movie.title }}
    </li>
</ul>

如何让视图显示每部电影的电影标题? 提前感谢您的宝贵时间。

【问题讨论】:

标签: json angular object jsonp observable


【解决方案1】:

始终检查网络选项卡以查看您是否实际接收数据以及该数据的外观。

对此进行测试。显然,您首先需要像这样构建您的网址:

return this.http.get('http://www.omdbapi.com/?s='+term)

那么关于响应,它是这样构建的:

{"Search":[{"Title":"24","Year":"2001–2010","imdbID"....

那么你需要提取什么来得到一个数组:

.map(response => {response.json().Search})

并订阅您的组件:

this.movieSearchService.search(term)
  .subscribe(d => this.movies = d)

然后当你想显示你的标题时:

<ul *ngIf="movies">
    <li *ngFor="let movie of movies">
        {{ movie.Title }}
    </li>
</ul>

请注意上述代码中的SearchTitle。这是区分大小写的,因此您需要使用 {{ movie.Title }} 和大写 T 来显示您的数据。

这应该可以解决问题! :)

【讨论】:

  • 感谢您的回复@AJT_82
  • 不客气! :) 如前所述,使用您的开发人员工具,例如按 F12 在 chrome 中。然后打开您的网络选项卡并检查请求并查看您是否收到响应。使用您的网址时,响应为空,这就是您无法迭代的原因。这是一张照片。检查我标记为黄色的部分:) imgur.com/a/RuClo
  • 对不起,这在我完成之前意外发布了我的答案。我收到一个错误:
    Argument of type '(term: string) => Subscription | Observable' 不可分配给“(值:字符串,索引:数字)=> ObservableInput”类型的参数。键入“订阅 | Observable' 不可分配给类型 'ObservableInput'。 
    我相信这是因为我将电影声明为可观察对象,例如电影: Observable Movie 包含结构(标题、年份等...)如果我不将其声明为可观察对象,我应该如何声明变量电影?
  • 你有Movie 接口或类吗?如果没有,您可以创建一个。但它也可以将数组声明为anymovies: any[] = [] 但我建议你创建一个界面。虽然这不是必需的,因为它对运行时没有影响。但如果不是为了别的,它支持编码。编译器和开发者自己:)
  • 是的,我有一个电影课。我已经用 Movie 类更新了代码。如果我不使用 any[] = [] ,从这里出发的正确路径是什么?
猜你喜欢
  • 2017-10-31
  • 2017-05-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
  • 2013-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多