简体   繁体   English

ngbModal.open 返回的 Promise 链被跳过

[英]Promise chain returned by ngbModal.open is skipped

I am implementing data editing in a component.我正在组件中实现数据编辑。 First I must check if one of data fields has been changed, and if so, a confirmation pop-up should open.首先,我必须检查其中一个数据字段是否已更改,如果是,则应打开一个确认弹出窗口。 If user confirms the change, the data will be updated.如果用户确认更改,数据将被更新。

From the updateData() method, I am calling the isChangeConfirmed() method which opens the pop-up and checks if the Save button was clicked on the pop-up.updateData()方法中,我调用isChangeConfirmed()方法,该方法打开弹出窗口并检查是否在弹出窗口上单击了“保存”按钮。 If so, it returns true .如果是,则返回true I expect the control to be returned to the updateData() method after calling the pop-up and checking the result.我希望在调用弹出窗口并检查结果后将控件返回给updateData()方法。 In the reality, the data is saved first, and then the pop-up window appears.现实中是先保存数据,然后弹出window。 What have I done wrong?我做错了什么?

component.html组件.html

<button id="saveButton" type="button" (click)="updateData()" translate>BUTTON.SAVE</button>


<!-- POPUP -->

<ng-template #editModal let-modal>
  <button type="submit" id="modalConfirmButton" (click)="modal.close('save')" class="btn btn-primary" translate>BUTTON.CONFIRM</button>
  <button type="reset" id="modalCancelButton" (click)="modal.close('cancel')" class="btn btn-primary" translate>BUTTON.CANCEL</button>
</ng-template>

component.ts组件.ts

updateData() {
  if (this.isChangeConfirmed()) {

    // Some code which updates data

  }
}

isChangeConfirmed(): boolean {
  if (this.oldValue != this.newValue) {
    this
      .ngbModal
      .open(this.editModal, { ariaLabelledBy: 'editModal' })
      .result
      .then((result) => {
        return result == "save";
      }, (reason) => {
        return false;
      });
  }
  return true;
}

The problem is when you open the modal, the part within (result) => { /*asynchronous part*/ } and (reason) => { /*asynchronous part*/ } runs asynchronously.问题是当您打开模式时, (result) => { /*asynchronous part*/ }(reason) => { /*asynchronous part*/ }中的部分异步运行。 It cannot be determined when these parts will run in comparison to the parts outside their context.与上下文之外的部分相比,无法确定这些部分何时运行。 Your return false;你的return false; statement is within the asynchronous context, but your return true;语句在异步上下文中,但您return true; is outside of it.在它之外。 So even if the return false;所以即使return false; piece runs, you cannot know when it will happen, because you don't know when this.ngbModal.open() will produce a result or a reason .一块运行,你不知道它什么时候会发生,因为你不知道this.ngbModal.open()什么时候会产生resultreason It seems like in your case not fast enough, and return true;在您的情况下,似乎速度不够快,并且return true; is faster.是比较快的。 But the point is that it's impossible to know.但关键是不可能知道。

This is all fine, but you can't put return true;这一切都很好,但你不能把return true; inside (result) => {... return true;} either, because I suppose the compiler will complain that there is no return statement. inside (result) => {... return true;}要么,因为我想编译器会抱怨没有 return 语句。

There are two ways to solve it that I can think of:我能想到的解决方法有两种:

  • You get rid of the separate function, put everything in one function, and put // Some code which updates data inside (result) => {... /* Some code which updates data*/ }您摆脱了单独的 function,将所有内容放在一个 function 中,然后放入// Some code which updates data (result) => {... /* Some code which updates data*/ }
  • Or if you really want to have a separate function, then what you need to do is not returning a boolean , but return an Observable , and subscribe to that Observable in updateData() .或者,如果您真的想要一个单独的 function,那么您需要做的不是返回boolean ,而是返回一个Observable ,并在updateData()中订阅该Observable Look it up how you can pipe the two answers, (result) and (reason) into one single Observable , how to join them, create an Observable out of this, and return that.查找如何将 pipe 两个答案(result)(reason)合并为一个Observable ,如何加入它们,从中创建一个Observable并返回它。

If you go with the second option, I suggest you look at RxJS Operators ( https://rxjs.dev/guide/operators ).如果您使用第二个选项 go,我建议您查看 RxJS 运算符( https://rxjs.dev/guide/operators )。 Also, reading articles on reactive programming can be useful.此外,阅读有关反应式编程的文章也很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM