2016-05-14 82 views
16

我正在学习Angular2和Typescript。我正在研究angular.io上的英雄教程,但将其应用到我从ASP.Net转换而来的项目中。我遇到了一个我认为是因为我缺乏理解的问题,但据我所知,它与本教程的相关部分相匹配。可观察<{}>不可分配到类型可观察<SomeType[]>

import { Injectable } from '@angular/core'; 
import {RiskListSummary} from '../Models/RiskListSummary'; 
import { Observable } from 'rxjs/Rx'; 
import { Http, Response } from '@angular/http'; 

@Injectable() 
export class RiskAssessmentListService { 

    constructor(private http : Http) {} 

    private serviceUrl = "http://myserviceurl/"; 

    getRisks(): Observable<RiskListSummary[]> { 
     return this.http.get(this.serviceUrl) 
      .map(this.extractData()) 
      .catch(this.handleError()); 
    } 

    private extractData(res: Response) { 
     if (res.status < 200 || res.status >= 300) { 
      throw new Error('Bad response status: ' + res.status); 
      } 
     let body = res.json(); 
     return body.data || { }; 
    } 

    private handleError (error: any) { 
     let errMsg = error.message || 'Server error'; 
     console.error(errMsg); // log to console instead 
     return Observable.throw(errMsg); 
    } 
} 

我收到以下错误就行了 “回归this.http.get(this.serviceUrl)”:

Error:(20, 16) TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. Type '{}' is not assignable to type 'RiskListSummary[]'. Property 'length' is missing in type '{}'.

如果它的确与众不同,我使用webstorm(最新版本),但我认为这个错误直接来自打字稿编译器。我在想也许我需要一个rxjs的打字文件,但教程不使用一个,而我发现的“打字搜索”中找不到的打了个差别

以下是我对软件包的依赖关系。 JSON:

"dependencies": { 
    "@angular/common": "2.0.0-rc.1", 
    "@angular/compiler": "2.0.0-rc.1", 
    "@angular/core": "2.0.0-rc.1", 
    "@angular/http": "2.0.0-rc.1", 
    "@angular/platform-browser": "2.0.0-rc.1", 
    "@angular/platform-browser-dynamic": "2.0.0-rc.1", 
    "@angular/router": "2.0.0-rc.1", 
    "@angular/router-deprecated": "2.0.0-rc.1", 
    "@angular/upgrade": "2.0.0-rc.1", 

    "systemjs": "0.19.27", 
    "es6-shim": "^0.35.0", 
    "reflect-metadata": "^0.1.3", 
    "rxjs": "5.0.0-beta.6", 
    "zone.js": "^0.6.12" 

回答

18

我觉得你的问题就设在这里:

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map(this.extractData()) <== passing result of function 
    .catch(this.handleError()); <== passing result of function 
} 

你可以使用只是路过function参考:

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map(this.extractData) 
    .catch(this.handleError); 
} 

但这样一来,你将失去this

或者你可以使用bind方法保留this

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map(this.extractData.bind(this)) 
    .catch(this.handleError.bind(this)); 
} 

然而,你将lose type checking

我将利用arrow功能能够使用lexical this

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map((res) => this.extractData(res)) 
    .catch((err) => this.handleError(err)); 
} 

没有它this将指向在调用时的功能。

+0

谢谢,这个技巧就是这样做的,我假设在原始示例中有.Net的扩展方法在工作(https: //angular.io/docs/ts/latest/guide/server-communication.html#)我想我需要开始一个新的项目,看看他们的例子是否仍然给出相同的错误 –

1

按照getRisks() FN,你是类型返回Observable<RiskListSummary[]>。但是,在您的代码中,您将返回body.data || {}。我相信你需要将你的RiskListSummary []与你的body.data连接起来。

+0

是的,这也可以(我改变了签名私人ExtractData由(RES:响应):RiskListSummary [])。作为来自C#的新的JavaScript开发人员,它对我来说比lambda函数更有意义。我不太确定这个语言的含义还没有说出哪个是最好的答案:-( –

1

我有同样的问题,但无论我如何改变如上所述,它仍然无法正常工作。直到我的大学发现了​​这个map, catch defination as VSC prompted

所以适当的变化应该是这样的(添加型投下面的地方)

getRisks(): Observable<RiskListSummary[]> { 
    return this.http.get(this.serviceUrl) 
    .map<RiskListSummary[]>(this.extractData) 
    .catch<RiskListSummary[]>(this.handleError); 
} 

我是新来的打字稿。所以这种[方法签名]真的给我的头:(

锤子但最后它的工作:)

-3

打字稿是一个编译器工具,它总会给类型检查的编译错误如在这里在这种情况下,getRisk方法应该指定它正在返回RiskListSummary类型的Observable,以便该工具能够识别该方法期望的内容,并在订阅方法中使用时检查类型安全性。

+0

“Typescript is一个编译器工具“?什么? –

相关问题