Angular:不存在可观察的模型属性

时间:2017-03-28 15:12:05

标签: rxjs observable angular4

从Angular 2升级到Angular 4后,在尝试使用AOT编译时出现这些错误:

Property 'total' does not exist on type 'Observable<any>'.

这是我迄今为止使用过observables的方式......

首先,我已经分配了一个这样的变量:

public myData: Observable<any>;

然后我打电话给我订阅了这样的服务:

this.mySubscription = this.apiService.get('URL-HERE')
                        .subscribe(
                            response => this.myData = response,
                            error => this.feedbackService.displayError(<any>error),
                            () => this.feedbackService.stopLoading()
                        );

这适用于开发模式(ng serve),我可以使用*ngFor之类的东西来迭代结果。

在收到这些错误后,我尝试添加这样的模型类:

export class MyData {
    total: number;
    count: number;
    data: Array<any> = [];
}
... rest of component here

然后将它与我的observable一起使用:

public myData: Observable<MyData>;

但是在尝试编译时我仍然会遇到错误:

Property 'total' does not exist on type 'Observable<MyData>'.

我做错了什么?

更新

这就是服务方法的样子:

return this.http
        .get(apiUrl + apiPath, {headers: headersWithToken})
        .timeoutWith(appSettings.maxTimeHttpCalls, Observable.defer(() => Observable.throw(this.feedbackService.timeout())))
        .map((response: Response) => {
            return response.json();
        })
        .catch((err: Response) => {
            return err.json();
        });

返回的JSON上存在所有值(包括total),我可以在我的HTML中使用它而不会出现问题。

3 个答案:

答案 0 :(得分:1)

原来AOT不喜欢Angular 4中的elvis运营商。

我在所有组件上保留Document doc = Jsoup.connect("https:// (enter a url)").get(); BufferedWriter writer = null; try { writer = new BufferedWriter( new FileWriter("d://test.txt")); writer.write(doc.toString()); } catch ( IOException e) { } 并将包含Observable<any>等内容的所有条目包含在{{myData?.total}}项检查中(并已删除?),错误消失了。

答案 1 :(得分:1)

我们在这里添加更多上下文,我认为您的错误实际上发生在component.html文件中吗?

基本上,你有类似的东西:

my-component.component.ts

@Component({
    selector: 'app-my-component',
    templateUrl: './my-component.component.html',
    styleUrls: ['./my-component.component.scss']
})
export class MyComponent implements OnInit {
    data$: Observable< MyType >;

    construct(private myService: MyService) {
        this.data$ = myService.getStuff();
    }
}

让我们假设您的服务my-service.service.ts如下:

@Injectable()
export class MyService {
    getStuff(): Observable< MyType > {
        this.http.get('www.example.com/data').map(res => res.json());
    }
}

最后,您的my-component.component.html目前看起来像这样:

<div class="my-data">
    {{data$?.global?.statistics | async}}
</div>

编译时会出现错误 Property 'global' does not exist on type 'Observable<MyType>'.

这是一个很好的理由。我们需要记住,我们正在使用可以持有可观察对象但可能不是可观察对象的对象。上面的HTML文件说的是data$global是对象的一部分,statisticsObservable。所以结构看起来像这样:

data$: {
    global: {
        statistics: Observable< MyType >;
    }
}

但实际上你想要的是:

data$: Observable< MyType >;

要解决此问题,您需要进入HTML并告诉它data$Observable而不是其中的对象:

<div class="my-data">
    {{(data$ | async)?.global?.statistics}}
</div>

现在它知道data$对象是Observable,后面的东西是返回对象的一部分,而不是Observable类。

答案 2 :(得分:0)

您在更改的编译器行为方面所看到的内容可能与aot相关更少,而且更新的打字稿更多(如果您使用的是早于我认为角度为2.4.9的任何内容,则必须使用打字稿2.0或更低,角4要求2.1或更高)。

鉴于升级到打字稿,您可能还需要重新访问您的tsconfig设置并确保它们仍然按照您的要求进行操作。