Typescript / Angular2:将 JSON 转换为与 Observable 和 JSONP 的接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37212948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:28:40  来源:igfitidea点击:

Typescript / Angular2: Cast JSON to interface with Observable & JSONP

typescriptangularjsonprxjsobservable

提问by safari

I'd like to cast my json-array to my interface which I've created and like to display it in the browser. I think there is probably something wrong with my interface but I can't figure it out... What do I need to change to get my code running?

我想将我的 json-array 投射到我创建的界面并希望在浏览器中显示它。我认为我的界面可能有问题,但我无法弄清楚......我需要更改什么才能运行我的代码?

Interface:

界面:

 export interface Video {
  id: number;
  name: string;
  description: string;
  createdAt: string;
}

app.ts

应用程序

import {JSONP_PROVIDERS, Jsonp} from '@angular/http';
import {Observable} from '../../../node_modules/rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/share';
import {Video} from './networking/api';

    private videoData: Observable<Video[]>;
    ngOnInit() {
                this.displayNewstVideo(10);
            }

            private displayNewstVideo(count: number) {
                this.videoData = this.jsonp
                .get('localhost:8080/video/newst/' + count + '?jsonp=JSONP_CALLBACK')
                .map(res => (res.json() as Video[]));
                alert(this.videoData.count);
            }

app.html

应用程序.html

<div class="container">
  <div class="video" style="font-family:sans-serif" *ngFor="#entry of videoData | async;  #i = index">
      <br *ngIf="i > 0" />
      <span class="title" style="font-size:1.2rem">
        <span>{{i + 1}}. </span>
        <a href={{entry.urlDesktop}}>{{entry.name}}</a>
      </span>
      <span> ({{entry.description}})</span>
      <div>Submitted at {{entry.createdAt * 1000 | date:"mediumTime"}}.</div>
    </div>

JSON

JSON

[{
id: 1,
name: "Some Name",
description: "BlaBla",
createdAt: "2016-05-04 13:30:01.0",
},
{
id: 2,
name: "Some Name",
description: "BlaBla",
createdAt: "2016-05-04 13:30:01.0",
}]

Edits

编辑

  1. I've checked if the request is correct in my network-tab in chrome and it is working as excepted: 200 OK --> Response ist also fine
  2. I edited my code as Thierry stated out and now it is finally showing the first object in my array :-)!! But I get following error now:
  1. 我已经检查了 chrome 网络选项卡中的请求是否正确,并且它正常工作:200 OK --> 响应也很好
  2. 我按照蒂埃里所说的那样编辑了我的代码,现在它终于显示了我数组中的第一个对象:-)!!但我现在收到以下错误:

Uncaught EXCEPTION: Error in app/html/app.html:27:11 ORIGINAL EXCEPTION: RangeError: Provided date is not in valid range. ORIGINAL STACKTRACE: RangeError: Provided date is not in valid range. at boundformat(native) at Function.DateFormatter.format (http://localhost:3000/node_modules/@angular/common/src/facade/intl.js:100:26) at DatePipe.transform (http://localhost:3000/node_modules/@angular/common/src/pipes/date_pipe.js:25:37) at eval (http://localhost:3000/node_modules/@angular/core/src/linker/view_utils.js:188:22) at DebugAppView._View_AppComponent1.detectChangesInternal (AppComponent.template.js:377:148) at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14) at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:289:44) at DebugAppView.AppView.detectContentChildrenChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:215:37) at DebugAppView._View_AppComponent0.detectChangesInternal (AppComponent.template.js:198:8) at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14) ERROR CONTEXT: [object Object]

Uncaught EXCEPTION: Error in app/html/app.html:27:11 ORIGINAL EXCEPTION: RangeError: 提供的日期不在有效范围内。原始堆栈跟踪:范围错误:提供的日期不在有效范围内。在boundformat在Function.DateFormatter.format((天然)的http://本地主机:3000/node_modules/@angular/common/src/facade/intl.js:100:26)在DatePipe.transform(HTTP://本地主机: 3000/node_modules/@angular/common/src/pipes/date_pipe.js:25:37) 在 eval ( http://localhost:3000/node_modules/@angular/core/src/linker/view_utils.js:188:22) 在 DebugAppView._View_AppComponent1.detectChangesInternal (AppComponent.template.js:377:148) 在 DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14) 在 DebugAppView.detectChanges ( http://localhost:3000/node_modules/@angular/core/src/linker /view.js:289:44) 在 DebugAppView.AppView.detectContentChildrenChanges ( http://localhost:3000/node_modules/@angular/core/src/linker/view.js:215:37) 在 DebugAppView._View_AppComponent0.detectChangesInternal ( AppComponent.template.js:198:8) 在 DebugAppView.AppView.detectChanges ( http://localhost:3000/node_modules/@angular/core/src/linker/view.js:200:14) 错误上下文:[object Object ]

采纳答案by Thierry Templier

You could try the following instead:

您可以尝试以下操作:

this.videoData = this.jsonp
    .get('localhost:8080/video/newst/' + count +
                      '?jsonp=JSONP_CALLBACK')
            .map(res => <Video[]>res.json();

Edit

编辑

I think that your request doesn't return JSONP content but classical one (JSON). If so, you could try the following:

我认为您的请求不会返回 JSONP 内容,而是返回经典内容 (JSON)。如果是这样,您可以尝试以下操作:

import { bootstrap }  from 'angular2/platform/browser';
import { Component } from 'angular2/core';
import { HTTP_PROVIDERS, Http } from 'angular2/http';
import "rxjs/add/operator/map";

@Component({
  selector: "app",
  templateUrl: "app.html",
  providers: [HTTP_PROVIDERS]
})
class App {
  private feedData: Observable<Video[]>;

  constructor(private http: Http) { }

  ngOnInit() {
    this.displayNewstVideo(10);
  }

  private displayNewstVideo(count: number) {
    this.videoData = this.http
      .get('localhost:8080/video/newst/' + count)
      .map(res => (res.json() as Video[]))
      .do(videoData => {
        console.log(videoData);
      });
  }
}

bootstrap(App);

回答by wolfhoundjesse

Try using a class instead of an interface, so in this case video.model.ts would be:

尝试使用类而不是接口,所以在这种情况下 video.model.ts 将是:

export class Video {
  constructor(
    public id: number,
    public name: string,
    public description: string,
    public createdAt: string){}
}

回答by David Pine

I gave a presentation of TypeScriptrecently, this reminded me of what of the slide's titles "There is no interface!" In TypeScriptwhen you define an interface, it actually compiles down to nothing. Which can be somewhat misleading. I think I understand what you're trying to do though:

我最近做了一个TypeScript的演示,这让我想起了幻灯片的标题“没有界面!” 在TypeScript 中,当您定义 时interface,它实际上编译为空。这可能有点误导。我想我明白你想要做什么:

The issue is the way that the JSONPobject comes back, it's padded. So it sits in the index [1]. Try this instead:

问题是JSONP对象返回的方式,它被填充。所以它位于索引中[1]。试试这个:

this.videoData = this.jsonp
    .get('localhost:8080/video/newst/' + count +
                      '?jsonp=JSONP_CALLBACK')
            .map(res => <Video[]>res.json()[1]);