angular - 错误 TS2339:“任何 []”类型上不存在属性“名称”
问题描述
我在 Angular 文档和 stackoverflow 上进行了搜索,但没有什么像我的问题。我可能不明白一些事情。但我的问题如下:
角 CLI:11.0.2 节点:14.15.1
我的服务:
export class ApiService {
constructor(private httpClient: HttpClient) { }
/**
* Get teams by id
* @param id
* @returns
*/
getTeamFromServe(id: number){
return this.httpClient.get('https://api.football-data.org/v2/teams/'+ id, {
headers: {
'X-Auth-Token': 'XXXXXXXXXXXXXXXXX'
},
observe: 'body',
responseType: 'text'
})
}
}
在我的组件中:
团队详细信息.components.js :
@Component({
selector: 'app-team-detail',
templateUrl: './team-detail.component.html',
styleUrls: ['./team-detail.component.scss']
})
export class TeamDetailComponent implements OnInit {
arrayTeamInfo: Array<any> = [];
constructor(private apiService: ApiService,
private router: Router,
private route: ActivatedRoute) { }
ngOnInit(): void {
const id = this.route.snapshot.params['id'];
this.apiService.getTeamFromServe(id).subscribe(
data => {
let arrayData = [];
arrayData = JSON.parse(data);
this.arrayTeamInfo = arrayData;
console.log(this.arrayTeamInfo);
}, err => {
this.arrayTeamInfo = JSON.parse(err.error).message;
}
)
}
}
结果 consol.log :
activeCompetitions: []
address: "null Rio de Janeiro, RJ null"
area: {id: 2032, name: "Brazil"}
clubColors: "Red / Black / White"
crestUrl: "https://crests.football-data.org/1783.svg"
email: null
founded: 1919
id: 1783
lastUpdated: "2020-09-10T02:18:46Z"
name: "CR Flamengo"
phone: null
shortName: "Flamengo"
squad: []
tla: "FLA"
venue: "Estadio Jornalista Mário Filho"
website: "https://www.flamengo.com.br/pagina-inicial-basquete"
团队详细信息.component.html :
<h1>
{{ arrayTeamInfo.name }}
</h1>
每个属性都会出现此问题,例如(地址、clubColors、电子邮件...)。我收到了这个错误:
Error: src/app/teams/team-detail/team-detail.component.html:9:38 - error TS2339: Property 'name' does not exist on type 'any[]'.
但是,如果我在我的 html 文件上执行此操作,它就可以工作:
<h1>
{{ arrayTeamInfo['name']}}
</h1>
我只是随机使用这种语法,我不明白为什么我必须在这里这样做,而在我创建的所有其他组件中(具有完全相同的结构)我没有问题......
我错过了一部分吗?
解决方案
在组件类中,您说:
arrayTeamInfo: Array<any> = []
所以arrayTeamInfo
肯定会是一个数组;它的名称以“array”开头,它有一个数组类型(Array<any>
与 相同any[]
),默认值为错误。完全清楚。您在接收数据时加强了这一点:
let arrayData = [];
arrayData = JSON.parse(data);
this.arrayTeamInfo = arrayData;
空数组值未使用,但确实将arrayData
("array" again!) 的类型设置为any[]
. 这是 100% 的数组,当然不会不是数组。正确的?但是然后在模板中,您可以:
<h1>
{{ arrayTeamInfo.name }}
</h1>
数组没有名称,因此当编译器对此进行类型检查时,自然会有些困惑。因此(完全准确的)错误:
Property 'name' does not exist on type 'any[]'.
在您的问题中,您向团队信息展示的不是一个数组,并说它arrayTeamInfo['name']
确实有效,所以问题是:您为什么要花这么多时间说服编译器您的价值将是一个数组,如果它不是?
那么如何解决呢?首先,您应该在代码库的某处表达团队信息的实际形状:
interface Team {
name: string;
area: {id: number; name: string};
/* ...other props */
}
然后,当您从服务器获取数据时,您实际上可以使用它,因此您的其余代码知道它应该期望接收什么 - 指定方法的返回类型,并使用泛型类型参数HttpClient#get
(参见https:/ /angular.io/guide/http#requesting-a-typed-response):
export class ApiService {
constructor(private httpClient: HttpClient) { }
getTeamFromServe(id: number): Observable<Team> {
return this.httpClient.get<Team>( // <- set this
`https://api.football-data.org/v2/teams/${id}`,
{
headers: {'X-Auth-Token': 'XXXXXXXXXXXXXXXXX'},
/* other options restated defaults or were wrong */
}
)
}
}
最后,在您的组件中,属性的类型实际上应该反映您计划分配给它的内容,因此编译器可以检查您编写的内容是否有意义:
@Component({
selector: 'app-team-detail',
templateUrl: './team-detail.component.html',
styleUrls: ['./team-detail.component.scss']
})
export class TeamDetailComponent implements OnInit {
teamInfo?: Team; // <- no initial value, so undefined until request completes
constructor(private apiService: ApiService,
private router: Router,
private route: ActivatedRoute) { }
ngOnInit(): void {
const id = this.route.snapshot.params['id'];
this.apiService.getTeamFromServe(id).subscribe(data => {
this.teamInfo = data; // <- data is typed as Team, so the compiler's happy
})
}
}
<h1>
{{ teamInfo?.name }}
<!-- safe navigation handles undefined default -->
</h1>
(请注意,组件不再需要JSON.parse
来自服务的数据 - 拥有单独服务的目的是从表示层抽象出传输层的细节,因此有类似“我们将数据作为 JSON string" 泄漏到组件中没有帮助。)
另一种选择是更倾向于使用可观察对象,使用| async
管道而不是需要安全导航;几年前我在我的博客上写过这个(使用旧Http
语法,但这些想法仍然有用)。
推荐阅读
- pandas - 在 Pandas Dataframe 中的两列上进行分组,其中一列上有 bin(范围)
- mongodb - 如何将字符串转换为 BSON
- bulk - ORACLE:如何在一个查询中批量收集主数据和详细信息?
- javascript - 如何避免元标记在 php 中运行
- mysql - SQL 使用 COUNT(*) AS CountOf 插入选择
- node.js - 构建一次性密码认证服务器
- javascript - 有没有办法从表单中获取值数组
- python - 从连续元素之间的差异小于特定数字的列表创建嵌套列表
- python - 我想将数据框转换为特定格式的数据框或列表列表
- shutdown - 为什么从 wildfly-maven-plugin 启动的 wildfly 服务器没有关闭?