【问题标题】:Angular: Observable model property does not existAngular:可观察的模型属性不存在
【发布时间】:2017-03-28 15:12:05
【问题描述】:

从 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();
        });

所有值(包括total)都存在于返回的 JSON 中,我可以毫无问题地在我的 HTML 中使用它。

【问题讨论】:

  • 试试这个public myData: MyData;
  • 如果this.myData = response 是可观察的,为什么它是? response 是什么东西的流?
  • 错误指的是哪一行?
  • 更新了我的服务电话中的示例。由于我在整个应用程序的所有 API 调用中都使用了此设置,因此在编译时出现了数百个此类错误。

标签: rxjs observable angular4


【解决方案1】:

原来 AOT 不喜欢 Angular 4 中的 elvis 运算符。

我在所有组件上保留Observable&lt;any&gt;,并将所有包含{{myData?.total}} 之类的内容的条目包装在*ngIf 检查中(并删除?)并且错误消失了。

【讨论】:

    【解决方案2】:

    让我们在这里添加更多上下文,我认为您的错误实际上是在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 类。

    【讨论】:

      【解决方案3】:

      您所看到的编译器行为变化可能与 aot 的关系较小,而与更新的 typescript 的关系更大(如果您使用的任何东西早于我认为的 angular 2.4.9,那么您必须使用 typescript 2.0或更低,角度 4 需要 2.1 或更高)。

      鉴于升级到 typescript,您可能还需要重新访问您的 tsconfig 设置并确保它们仍在执行您想要的操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-01
        • 1970-01-01
        • 2017-02-27
        • 2018-11-03
        • 1970-01-01
        • 1970-01-01
        • 2021-11-22
        • 2018-12-05
        相关资源
        最近更新 更多