【问题标题】:Angular : Perfoming successive HTTP-Delete in a loop doesn't workAngular:在循环中执行连续的 HTTP-Delete 不起作用
【发布时间】:2021-08-09 14:08:30
【问题描述】:

我正在开发一个使用 Angular CRUD 操作的网站,但我很难对我的数据库执行连续删除。

我在一个名为 « this.checkedLogs » 的数组中恢复了需要从数据库中删除的 ID(这部分确实有效)。
然后,当我单击一个按钮时,我会调用一个用于执行这些删除的函数:« onModalConfirm »
问题是它运行得太快了,以至于我的迭代器没有时间改变它的值和要从我的数组中删除的实际 ID,以至于函数已经循环了。
此外,在循环结束时,条件 « if (this.checkedLogs.length == 0) » 不成立,这表明它运行得如此之快。

我正在考虑添加等待功能,但我不知道这是否符合良好的做法。 我仍然是 Angular 的初学者,对 Observable 周围的一切还不太熟悉。

  • 这是我的 service.ts :
deleteLogsByID(id: number): Observable<any> {
    return this._httpClient.delete(`${API_BASE_URL}/delete/id/${id}`, {responseType: 'text'});
  }
  • 这是我的 component.ts:
deleteLogsByID(id: number): void {
        this.logsSubscription = this.LogsService.deleteLogsByID(id).subscribe(
            (data: any) => {
                this.deleteMessage = data;
            },
            (error: HttpErrorResponse) => {
                this.showSpinner = false;
                this.error = error.message;
                this.showError = true;
            }
        );
    }

onModalConfirm() {
        /** Getting the length of my array by updating this.selectionAmount */
        this.updateSelectionAmount();

        /** If it’s not empty */
        if (this.selectionAmount != 0) {

            let iterator = this.checkedLogs.values();
            for (let index = 0; index < this.selectionAmount; index++) {
                /** Getting the id of the iterator */
                let id: number = iterator.next().value;

                /** Calling my delete function */
                this.deleteLogsByID(id);


                /** Removing the id from the array */
                this.checkedLogs.splice(id, 1);
            }

            /** When everything is done, reload the page */
            if (this.checkedLogs.length == 0)
                window.location.reload()
        }
    }

updateSelectionAmount() {
        this.selectionAmount = this.selection.selected.length;
    }
  • html 代码在我的问题中似乎并不重要,但这是我的删除函数的后端代码(运行良好):
@ApiOperation(value = "Delete a logs by its id", produces = "application/json")
@PreAuthorize("hasRole('MODERATOR') or hasRole('ADMIN')")
@DeleteMapping("/delete/id/{id}")
public ResponseEntity<String> deleteLogsById(@PathVariable Integer id) {

    Integer idRemoved = logsService.deleteLogsById(id);

    if (idRemoved == 0)
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);

    String responseReturn = "Logs removed with id " + id;

    return new ResponseEntity<>(responseReturn, HttpStatus.OK);
}

提前致谢!

【问题讨论】:

  • 您是否可以扩展您的后端以能够处理接受 Id 的集合以及单数 Id?这可能会更健壮一些,并且不会产生那么多的网络请求。
  • 我明白你的意思,这可能是一个不错的选择!如果我的理解正确,我需要创建一个新端点,通过将数组传递到请求正文中来执行多次删除?

标签: angular crud angular2-observables http-delete


【解决方案1】:

是的,你没看错,for循环执行得很快,它调用了一堆请求,并在请求执行之前拼接了checkedLogs。不知道你所有的应用程序逻辑,但我建议使用好的旧回调来使删除操作有点顺序。 onModalConfirm 类似于:

onModalConfirm() {
    /** Getting the length of my array by updating this.selectionAmount */
    this.updateSelectionAmount();

    /** If it’s not empty */
    if (this.selectionAmount != 0) {
        let iterator = this.checkedLogs.values();
        const callDelete = () => {
            let id: number = iterator.next().value;
            const continueFn = (id) => {
                if (id !== undefined) {
                    callDelete();
                }
            }
            if (id !== undefined) {
                this.deleteLogsByID(id, continueFn);
            }
        }
        callDelete();
    }
}

而 deleteLogsByID 将是:

deleteLogsByID(id: number, callbackFn: (id: number) => void): void {
    this.logsSubscription = this.LogsService.deleteLogsByID(id).subscribe(
        (data: any) => {
            this.deleteMessage = data;
            callbackFn(id)
        },
        (error: HttpErrorResponse) => {
            this.showSpinner = false;
            this.error = error.message;
            this.showError = true;
            callbackFn(id);
        }
    );
}

【讨论】:

  • 嗨@MRsa,感谢您的回复!我理解回调的逻辑,但我不熟悉这个语法:“const callDelete=()=> {...}”我会搜索一下。此外,我测试了您编写的代码,似乎 deletelogsByID(...) 的调用次数比它应该调用的次数多两次。但由于我不熟悉语法我无法解决它
  • const fnName = () =>{} 与(仅绑定 this 不同)几乎相同 const fnName = function () {} 无论如何我认为 array.splice 中的问题 - 参数是错误的(第一个参数应该是开始 postiton 而不是 Id 值)我改变了答案,只需检查循环结束时的迭代器是否返回“未定义”或其他内容并更改代码。让遍历数组的迭代器在同一个函数(拼接)中也发生变化是个坏主意
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 2015-04-14
  • 2019-11-02
  • 2023-01-03
  • 2014-03-28
  • 1970-01-01
  • 2013-05-12
相关资源
最近更新 更多