防止模态出现错误时关闭

问题描述 投票:0回答:2

我使用了一种通用方法,在添加食品时,将打开一个带有表单的模式,让用户添加他的详细信息。但是,为了检查后端是否有重复项目,我只能在 API 调用完成后检索它。

问题是,如果出现错误,我不希望模式关闭,因为用户必须再次填写所有详细信息。

这是我的代码。我已经使用了第三方库来实现模态和吐司。

food.component.ts:

addFood(data: any){
    this.api.request('foodItem', 'POST', data).subscribe({
        next: (response: any) => {
            if (response.message == 'Added Successfully.') {
                this._toastService.showSuccess('Food added.');
            } else {
                this._toastService.showError(response.message);
            }
        },
        complete: () => this.getFood(),
        error: (error: any) => this._toastService.showError(error.message)
    });
}

食物组件.html

 <app-custom-table [tableData]="tableData" [form]="formData" [columnArray]="columnArray" (onAdd)="addFood($event)" (onEdit)="editFood($event)"></app-custom- 
 table>

自定义 - table.component.html

<button type = "button" class="btn btn-link"(click) = "openModal()"[disabled] = "isRowSelected"><span>Add</span></button>
<button type="button" class="btn btn-link"(click) = "openModal(selectedRow)"[disabled] = "isRowNotSelected"></i><span>Edit</span></button>

自定义-table.component.ts:

openModal(rowData: any = null) {
    const config: Partial<DynamicFormComponent> = {
        form: this.form,
        data: rowData
    };

    const options: NgbModalOptions = { size: 'sm', centered: true };

    const modalRef = this.ModalService.show((DynamicFormComponent), config, options).

modalRef.componentInstance.submitSubject.subscribe((result: any) => { //here getting error Property CoponentInstance does not exist in type Observable<ModalResult<unknown>>
        if (result.Success == true && result.Data) {
            if (rowData) {
                const updatedRowData = { ...rowData, ...result.Data };
                // If rowData is provided, it's an edit operation
                this.onEdit.emit(updatedRowData);
            } else { //add
                this.onAdd.emit(result.Data);
            }
        }
    });
}

动态表单.html

 @Output() submitSub: Subject<any> = new Subject<any>();
 constructor(
  private activeModal: NgbActiveModal
 ){
 

}

  onSubmit(){
  if(this.dynamicFormGroup.valid){
    this.submitSubject.next(this.dynamicFormGroup.value)  
   this.activeModal.close(this.dynamicFodmGroup.value) --not sure here
  }


  }

如何解决这个问题?

javascript .net angular typescript bootstrap-4
2个回答
0
投票

您可以根据自己的情况取消

hide.bs.modal
活动

$("#exampleModal").on("hide.bs.modal", function(event) {
  if (!document.querySelector("#defaultCheck1").checked) {
    event.preventDefault();
  }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
  Launch demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="form-check">
          <input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
          <label class="form-check-label" for="defaultCheck1">
    Allow Closing
  </label>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>

      </div>
    </div>
  </div>
</div>


0
投票

不使用“关闭”。在模态组件中添加主题,并在打开时订阅。是打开弹窗的组件还是关闭弹窗的组件

//in your component in a popup
    @Input() form: FormGroup;
    submit:Subject<any>=new Subject<any>()

//in .html
<div class="modal-header">
  <h4 class="modal-title">Hi there!</h4>
  <button type="button" class="btn-close" aria-label="Close"
           (click)="activeModal.dismiss()"
  ></button>
</div>
<div class="modal-body">
  <p>Hello, {{ name }}!</p>
  <!--A typical form-->
  <div [formGroup]="form">
    <input formControlName="name" />
  </div>
</div>
<div class="modal-footer">
  <button
    type="button"
    class="btn btn-outline-dark"
    <!--see that only emit one value to the "submit" subject -->
    (click)="submit.next(form.value)"
  >
    Close
  </button>
</div>

然后,打开时

  open() {
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
    modalRef.componentInstance.form = this.form;
    modalRef.componentInstance.submit
      .pipe(takeUntil(modalRef.closed))
      .subscribe((data: any) => {
        //I use a simple service that return "true" or "false"
        this.dataService.checkData(data.name).subscribe((res: any) => {
          if (res) modalRef.close(); //<--this close the popUp
        });
      });
  }

A stackblitz(只有在“名称”中写下“Angular”时才会关闭)

注意:您可以改进指示“表单”无效的原因,或者您可以使用自定义异步验证器。

更新简要说明

在 ngb-popup 中,我们可以在自己的函数“show”中订阅:

this.ModalService.show((DynamicFormComponent), config, options).subscribe(...)

或者使用变量并订阅后

//get a reference of the "popup"
const modalRef = this.ModalService.show((DynamicFormComponent), config, options)

//Subcribe to it
modalRef.subscribe(...)

我们需要采取第二种方法。

如果在我们的“DynamicFormComponent”中我们定义了“任何公共变量”,我们就可以访问它。这就是我们可以将变量添加到 DynamicFormComponent 的原因

submitSubject:Subject<any>=new Subject<any>()

现在,我们可以“订阅这个主题”了,所以

//really we use takeWhile to unsubscribe when the modal is closed
modalRef.componentInstance.submitSubject.subscribe((data: any) => {}

在我们的 DynamicFormComponent 中我们不使用“close”。我们不使用 close,而是向主题“发出”一个值

 // instead of use in .html
 (click)="activeModal.close(value)"
 //we use
 (click)="submitSubject.next(value)"

现在,我们在关闭时订阅的所有代码都用于主题的订阅。请记住,如果一切正常,我们需要手动(通过代码)关闭弹出窗口,使用

modalRef.close();
© www.soinside.com 2019 - 2024. All rights reserved.