首页 > 解决方案 > 在 Angular 中设置“配置文件详细信息”页面时,TypeScript“类型上不存在属性”错误

问题描述

我知道这是一个非常简单的问题,但我还没有找到可以以完全有意义的方式工作或解释的资源解决方案。多年后我试图回到 Angular 并且之前从未使用过 TypeScript。目前正在为错误和 TypeScript 实际期望我做的事情而苦苦挣扎。

我有一个连接到Open Brewery DB的应用程序。我正在尝试制作一个基于:idURL 参数获取数据的详细信息页面。

我有一个获取 Breweries 列表的列表组件。因此,无论返回什么都会显示在列表中。

http.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { IBrewery } from './brewery/brewery';

@Injectable({
  providedIn: 'root'
})
export class HttpService {

    constructor(private http: HttpClient) { }

    getBreweries() {
        return this.http.get('https://api.openbrewerydb.org/breweries');
    }

    getBrewery(id) {
        return this.http.get<IBrewery[]>(`https://api.openbrewerydb.org/breweries/${id}`)
    }
}

list.component.ts

import { Component, OnInit } from '@angular/core';

import { HttpService } from '../http.service';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.scss']
})
export class ListComponent implements OnInit {

    breweries: Object;

  constructor(private _http: HttpService) { }

  ngOnInit(): void {
        this._http.getBreweries().subscribe(data => {
            this.breweries = data;
        });
  }

}

list.component.html

<h1>Breweries</h1>

<ul *ngIf="breweries">
    <li *ngFor="let brewery of breweries">
        <p class="name">{{ brewery.name }}</p>
        <p class="country">{{ brewery.country}}</p>
        <a href="{{brewery.website_url}}" class="site" target="_blank">Visit Website</a>
    </li>
</ul>

所以所有这一切都没有错误一切似乎都很好......然后是配置文件和事情发生故障的地方。

brewery.component.ts

import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from '@angular/router';

import { HttpService } from '../http.service';

@Component({
  selector: 'app-brewery',
  templateUrl: './brewery.component.html',
  styleUrls: ['./brewery.component.scss']
})

export class BreweryComponent implements OnInit {

    brewery: object = {};
    breweryId: string;

  constructor(private _http: HttpService, private activatedRoute: ActivatedRoute) { }

  ngOnInit(): void {
        this.breweryId = this.activatedRoute.snapshot.params.id;
        this._http.getBrewery(this.breweryId).subscribe(data => {
            this.brewery = data;
        })
    }

}

brewery.component.html

<ul *ngIf="brewery">
    <li>
        {{brewery.name}}
    </li>
    <li>
        {{brewery.city}}, {{brewery.state}}
    </li>
</ul>

啤酒厂.ts

export interface IBrewery {
    name: string,
    city: string,
    state: string
};

我得到的错误是: - ERROR in src/app/brewery/brewery.component.html:7:13 - error TS2339: Property 'name' does not exist on type 'object'. - Error occurs in the template of component BreweryComponent. src/app/brewery/brewery.component.html:10:13 - error TS2339: Property 'city' does not exist on type 'object'. -Error occurs in the template of component BreweryComponent. src/app/brewery/brewery.component.html:10:31 - error TS2339: Property 'state' does not exist on type 'object'.

所以我认为的问题是,brewery在我可以在组件模板中声明它们之前,需要分配与这些属性关联的属性和类型。如果这是真的,对于我的生活,我无法弄清楚我应该如何或在哪里IBrewery正确使用它。我已经看到了servicemycomponent.component.ts文件中使用它的示例。在任何一种情况下,如何解决问题都非常清楚。

标签: javascriptangulartypescript

解决方案


简短答案:使用安全导航运算符

如下更新您的 html。

<ul *ngIf="brewery">
    <li>
        {{brewery?.name}}
    </li>
    <li>
        {{brewery?.city}}, {{brewery?.state}}
    </li>
</ul>

更好的方法:使用加载微调器。

<div *ngIf="loading">
  some loading spinner
</div>

<div *ngIf="!loading">
    <li>
        {{brewery?.name}}
    </li>
    <li>
        {{brewery?.city}}, {{brewery?.state}}
    </li>
</ul>


export class BreweryComponent implements OnInit {

    brewery; // be default type will be any. 
    breweryId: string;
    loading = false; // loading spinner.

    constructor(private _http: HttpService, 
               private activatedRoute: ActivatedRoute) { }

    ngOnInit(): void {

        this.breweryId = this.activatedRoute.snapshot.params.id;
        this.get();

    }

    get() {

        this.loading = true;
        this._http.getBrewery(this.breweryId)
             .subscribe(data => {

            this.brewery = data;
            this.loading = false; // loading spinner hidden.

        }, (error) => {

            // handle error;

        });

    }

}

推荐阅读