Angular 有条件地关闭 bootstrap 模式

Angular close a bootstrap modal conditionally

我在 Angular 应用程序中有这个模式:

<ng-template #content let-modal>
  <div class="modal-header">
    <h2 class="modal-title" id="modal-basic-title">{{saveTitle}}</h2>
    <button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <app-add-program [model]="model" [showNavBar]="false" title=""></app-add-program>
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-outline-dark" (click)="modal.close('Save click')">{{saveButtonTitle}}</button>
  </div>
</ng-template>

我认为 app-add-program 部分对于回答这个问题不是必需的,但如果您需要查看它,请告诉我。

这是该模态的打开函数:

  open(content): void {
    // @ts-ignore
    this.modalReference = this.modalService.open(content, {ariaLabelledBy: 'modal'}).result.then((result) => {
      this.pds.programCast.subscribe((data) => {
          if (result === 'Save click'){
            const editedProgram = data;
            console.log('Edited program: ', editedProgram);
            const validity = this.programService.validateModel(editedProgram);
            console.log('Validity check...');
            if (validity.isValid === true) {
              console.log('Validity was true.');
              // If the program needs to be approved and activated then mark it approved
              if (editedProgram?.approved === false){
                editedProgram.approved = true;
              }
              if (editedProgram?.active === false){
                editedProgram.active = true;
              }
              console.log(editedProgram);
              console.log('Starting api call...');
              if (editedProgram != null && editedProgram !== undefined) {
                this.programService.editProgram(editedProgram).subscribe({
                  // tslint:disable-next-line:no-shadowed-variable
                  next: result => {
                    this.wasSuccessful = true;
                    console.log('It was successful');
                    this.snackBar.open('Your changes have been saved.');
                    this.modalReference.close();
                  },
                  error: err => {
                    this.wasSuccessful = false;
                    console.log('It failed: ', err.statusText);
                    this.snackBar.open('There was an error saving your changes. Error Status ' + err.status + ': ' + err.statusText);
                  }
                });
              }
            } else {
              console.log('Validity was false.');
              this.snackBar.open(validity.reason);
            }
          } else {
            this.closeResult = `Closed with: ${result}`;
          }
      });
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
  }

我想要的不是在 html 中调用 modal.close 而是调用一个函数来调用 API 并使用 this.modalReference.close() 关闭模态,如果它成功,如果不成功,则保持模式打开。

所以基本上,这部分需要执行:

     const editedProgram = data;
            console.log('Edited program: ', editedProgram);
            const validity = this.programService.validateModel(editedProgram);
            console.log('Validity check...');
            if (validity.isValid === true) {
              console.log('Validity was true.');
              // If the program needs to be approved and activated then mark it approved
              if (editedProgram?.approved === false){
                editedProgram.approved = true;
              }
              if (editedProgram?.active === false){
                editedProgram.active = true;
              }
              console.log(editedProgram);
              console.log('Starting api call...');
              if (editedProgram != null && editedProgram !== undefined) {
                this.programService.editProgram(editedProgram).subscribe({
                  // tslint:disable-next-line:no-shadowed-variable
                  next: result => {
                    this.wasSuccessful = true;
                    console.log('It was successful');
                    this.snackBar.open('Your changes have been saved.');
                    this.modalReference.close();
                  },
                  error: err => {
                    this.wasSuccessful = false;
                    console.log('It failed: ', err.statusText);
                    this.snackBar.open('There was an error saving your changes. Error Status ' + err.status + ': ' + err.statusText);
                  }
                });
              }
            } else {
              console.log('Validity was false.');
              this.snackBar.open(validity.reason);
            }

然后在 next 子句中调用 this.modalReference.close() 或保持打开状态并显示它在 error 子句中显示的弹出消息。

我知道我已经编写了大部分代码,但出于某种原因,我只是想不出如何编写代码以按该顺序执行。

如果您需要任何进一步的信息来回答这个问题,请告诉我。

更新:

open(content): void {
    // @ts-ignore
    this.modalReference = this.modalService.open(content, {ariaLabelledBy: 'modal'}).result;
  }
  private validateAndSave(closeReason) {
    if (closeReason === 'Save click') {
        const editedProgram = this.model;
        console.log('Model: ', this.model);
        console.log('Edited program: ', editedProgram);
        if (editedProgram != null && editedProgram !== undefined) {
          const validity = this.programService.validateModel(editedProgram);
          if (validity.isValid === true) {
            console.log('Validity was true.');
            // If the program needs to be approved and activated then mark it approved
            if (editedProgram?.approved === false) {
              editedProgram.approved = true;
            }
            if (editedProgram?.active === false) {
              editedProgram.active = true;
            }
            this.programService.editProgram(editedProgram).subscribe({
              next: result => {
                this.wasSuccessful = true;
                console.log('It was successful: ', result);
                this.snackBar.open('Your changes have been saved.');
                this.modalReference.close();
              },
              error: err => {
                this.wasSuccessful = false;
                console.log('It failed: ', err.statusText);
                this.snackBar.open('There was an error saving your changes. Error Status ' + err.status + ': ' + err.statusText);
              }
            });
          } else {
            console.log('Validity was false.');
            this.snackBar.open(validity.reason);
          }
        }
    } else {
      this.modalReference.close();
    }
  }
<button type="button" class="btn btn-outline-dark" (click)="validateAndSave('Save click')">{{saveButtonTitle}}</button>

我相信我已经完成了第一个答案建议的所有操作,但是在尝试关闭模式时出现此错误:

[Error] ERROR – TypeError: _this.modalReference.close is not a function.

您正在执行模态 resolve 路径中的所有代码。

为避免这种情况,只需创建一个新函数(validateAndSave 或类似的函数)并将所有逻辑从 open 函数的第三行开始移动

那就是这部分:

this.pds.programCast.subscribe((data) => {...}

但是您必须删除该块的第一个 if,即检查的那个:

if (result === 'Save click') {...}

因此,当您到达 wasSuccessful 案例时,您只需调用 this.modalReference.close()

最后,在您的模板中调用 validateAndSave 函数而不是 modal.close:

<button type="button" class="btn btn-outline-dark" (click)="validateAndSave()">{{saveButtonTitle}}</button>

不要忘记删除打开模式行的 .then 部分,这样它只会打开模式并将引用存储在 this.modalReference