我有一个Angular 7应用,该应用正在从两个单独的端点中检索数据:
http://localhost:1337/sms
http://localhost:1337/total
我可以成功地向开发中的这些端点发出GET请求。但是,运行ng build --prod
时出现以下错误:
ERROR in src/app/app.component.html(20,29): : Property 'total' does not exist on type 'object'.
作为一项测试,我暂时从app.component.html中删除了{{ total.total }}
,再次运行了ng build --prod
并成功了。
这是向两个单独的端点发出GET请求的正确方法吗?或者我在Node服务器文件中做错了其他事情吗?
app.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
signees: object;
total: object;
constructor(private http: HttpClient){}
ngOnInit(): void {
this.http.get('http://localhost:1337/sms').subscribe(
data => {
this.signees = data;
}
);
this.http.get('http://localhost:1337/total').subscribe(
data => {
this.total = data;
}
);
}
}
相关的 app.component.html 代码
<section class="page-section mx-auto">
<h3 class="text-center">{{ total.total }} people have signed the petition</h3>
<div class="container">
<div class="row">
<div class="col-sm-6 col-lg-3"
*ngFor="let signee of signees; index as i">
<div class="card">
<div class="card-body">
<p class="h2">{{ signee.name }}</p>
<ul class="signee-meta text-muted">
<li>#{{ i + 1 }}</li>
<li>{{ signee.date }}</li>
</ul>
</div>
</div>
</div>
</div><!-- row -->
</div><!-- container -->
</section>
/total
端点(MongoDB)
app.get('/total', (req, res) => {
collection.countDocuments({}, function(err, num) {
assert.equal(null, err);
res.send({total: num});
});
});
编辑(添加的数据结构)
数据结构(MongoDB)
{
"_id" : ObjectId("5c61e0b658261f10280b5b17"),
"name" : "Bill Kickok",
"number" : "+14950395584",
"date" : "2/11/19"
}
答案 0 :(得分:1)
运行ng build --prod
时会引发此错误,因为这种构建过程在幕后可用于Ahead of Time编译。
这是基于angular documentation的AOT上发生的事情。
更早地检测模板错误
AOT编译器在以下过程中检测并报告模板绑定错误 用户看到它们之前的构建步骤。
之所以会出现此错误,是因为在将total
声明为object
时,您尝试渲染总对象的属性。
为了摆脱此错误,您应该为此变量创建一个interface
。例如
export interface Total {
total: number
// any other properties total might include
}
然后使用此接口在组件中像这样定义类型:
total: Total
如果您不想创建一个界面-这是一个不好的习惯,则可以将总计定义为any
(total: any
)。
最后,直接在组件中发出http
请求也是一种坏习惯。您应该创建一个服务,然后添加负责与后端通信的methods
,然后将该服务注入组件并调用该方法。
我建议您进一步研究angular documentation。
答案 1 :(得分:0)
如果可能的话,强烈键入这些属性是个好主意,因此,代替:
signees: object;
total: object;
如果是这样:
signees: Signee[];
total: Total;
其中Signee
和Total
是接口:
export interface Signee {
id: number;
name: string;
date: string;
// ...
}
export interface Total{
id: number;
total: number;
// ...
}
注意:上面的内容与data
中返回的JSON结构相匹配(这就是为什么有人问您data
的结构是什么样的原因。
如果总数只是您收到的一个数字,那么它将是:
total: number;
您只需绑定到total
,而不是total.total
。
然后在发送请求时可以使用这种强类型输入,以确保响应的格式正确:
this.http.get<Signee[]>('http://localhost:1337/sms').subscribe(
data => {
this.signees = data;
}
);
请注意上面代码中指定的通用参数。
答案 2 :(得分:0)
您需要在构造函数内部启动对象。
例如:
constructor(private http: HttpClient){
total = new Total();
}
总计是您的课程。这是在angular.io中推荐的。在构造函数中启动VAR。