angular - 防止在 Angular 应用条件逻辑中无限调用 API
问题描述
我试图了解为什么我的 Angular 应用程序中的某些逻辑会导致对 API 的无限调用。很清楚的是,我想确定一种更好的方法来做到这一点。
首先,在我看来,我对一个看起来像这样的按钮进行了一些验证:
<button md-button (click)="completeCategory()"
[disabled]="!canComplete()"
[class.button-disabled]="!canComplete()">Complete
</button>
现在,作为组件中验证的一部分,我调用 API 来检查一些数据:
public async isDocSigned() {
const customerId = this.customer._id;
const type = 'catOrig';
const response: any = await this.stageService.checkSignedDoc(customerId, type);
// Look for errors
if (!response || response.ok !== true)
{
let message = 'Failed to obtain signature data';
console.error(message, response);
return;
}
if (response && response.count > 0) {
return true;
} else if (response && response.count < 1) {
return false;
}
}
顺便说一下,上面调用的服务函数是这样的:
public async checkCustomerSigned(customerId, type) {
return await API.service.send({
reqType: 'get',
req: `customers/validation/ptlDocument`,
reqArgs: { customer: customerId, type: type }
});
}
我将返回的 API 响应用作条件逻辑的一部分,以查看是否canComplete()
应启用带有按钮的按钮。
考虑到两个条件因素。1.) 文档是否处于正确阶段,以及 2.) 如果是 s,文档是否已签名:
public async canComplete() {
if (this.selectedService.category['stage'] === 'awaiting signature from customer') {
const docSigned = await this.isDocSigned();
if (docSigned) return true;
if (!docSigned) return false;
}
}
因此,通过测试这段代码,很明显该isDocSigned()
函数会一遍又一遍地调用 API。
我认为这是因为 Angular 在视图中看到了带有该canComplete()
功能的按钮,然后不断地评估它?
当文档处于此阶段时,我最终看到的是这个 console.log 行一遍又一遍地打印到屏幕上:
`console.error(message, response);`
那么有什么更好的方法来处理这个问题呢?我应该放入isDocSigned()
构造函数,还是像这样的生命周期钩子ngOninit()
?我该如何解决这里的无限调用?理想情况下,我只想进行一次此 API 调用。我真的很感激一个如何做到这一点的例子。一个简单的 stackBlitz 示例将非常有帮助。
解决方案
首先是由于 Angular Change Detection 而调用 API 的原因。在您的 HTML 文件中,您正在调用一个函数,而 Angular 不知道该函数的返回类型是否已更改。因此,它会继续执行导致无限 API 调用的函数。下面是错误代码:
[class.button-disabled]="!canComplete()"
强烈建议不要在模板中使用函数。这可以更改为使用以下内容:
[class.button-disabled]="!docSigned"
并将 canComplete() 方法移动到 ngOnInint。请注意,这将限制对 API 的调用仅在页面加载时。
推荐阅读
- android - Jetpack Compose BackPressHandler 在 onResume 后无法拦截回压
- python - 从多个文本文件在 python 上构建向量
- javascript - 有没有办法模拟 SVGTextElement 以便能够使用 Jest 测试使用 getBBox() 来测量文本的函数?
- python - 在 Amazon、Ebay 和 Warehouse 之间同步的 Python 自动库存盘点
- r - 带有来自数据框的输入的 RSQLite dbGetQuery
- mongodb - 无法安装 msi 文件。出现错误“Windows 无法访问指定的......访问该项目”
- datetime - 如何在 Elasticsearch 的 Lucene 日期范围查询中指定日期格式?
- python - 如何使用python中的其他值对数据进行排序?
- webserver - 如何使用 ESP-IDF 将二进制数据(html + favicon)上传到 ESP32?
- r - 使用 UDF 在 R 数据框中添加 6 小时