需要知道监听 rxjs Observable 的函数何时收到答案

need to know when answer received by function that listens to rxjs Observable

如何使用在 if 语句中 returns 的可观察对象上启动侦听器的方法?

我在一个 Angular 5 项目中,我在我的一个组件中进行了这种设置,其中有一个时间轴,双击打开一个模式,您可以输入您想要的项目的名称正在创建该模态。

对于模态,我使用了 的重制版本。 (我需要更多最新的语法和导入)。

我现在几乎可以正常工作了,这是我的设置,

(打开模式的时间轴组件):

@Component({
  selector: 'app-planning',
  templateUrl: './planning.component.html',
  styleUrls: ['./planning.component.css']
})
export class PlanningComponent implements AfterViewInit {

  options = {
    onAdd: (item, callback) => {
      if(this.timeline.getCurrentTime() > item.start){

        this.errorTimelineItemModal();
        callback(null);

      } else {
          if (this.createNewTimelineItemModal()) { // <-- currently I have no return but
                                                  //   having one would be meaningless
                                                 // anyways because the if wouldn't wait
                                                // for the observable response and as a
                                               // result, it would always assess false.
          callback(item);

        } else callback(null);
      }
    }
  }


  constructor(
      private _element: ElementRef,
      private modalService: BsModalService
  ) {}

  ngAfterViewInit(){
    this.container = this._element.nativeElement.querySelector('#timeline');
    if (!this.items) {
      this.items = new vis.DataSet(this.mydataset);
      this.timeline = new vis.Timeline(this.container, this.items, this.groups, this.options);
    }
  }

  createNewTimelineItemModal() {
    const initialState = {
      title: 'Ajouter',
      multipleChoice: 'Bid',
      choices: ['Bid', 'D.C.', 'Kickoff'],
      accceptBtnName: 'Ajouter',
      closeBtnName: 'Annuler',
    };
    this.bsModalRef = this.modalService.show(Modal, {initialState});
    this.bsModalRef.content.onClose.subscribe(result => {
        this.createItemResult = result;
        console.log(JSON.stringify(result));
    })
  }

  updateTimelineItemModal(name) {
    const initialState = {
      title: 'Nouveau Nom ?',
      itemCurrentName: name,
      accceptBtnName: 'Rennomer',
      closeBtnName: 'Annuler',
    };
    this.bsModalRef = this.modalService.show(Modal, {initialState});
    this.bsModalRef.content.onClose.subscribe(result => {
        this.createItemResult = result;
        console.log(JSON.stringify(result));
    })
  }

  deleteTimelineItemModal() {
    const initialState = {
      title: 'Êtes-vous sûr de vouloir supprimer cet element?',
      accceptBtnName: 'Supprimer',
      closeBtnName: 'Annuler',
    };
    this.bsModalRef = this.modalService.show(Modal, {initialState});
    this.bsModalRef.content.onClose.subscribe(result => {
        this.createItemResult = result;
        console.log(JSON.stringify(result));
    })
  }

  errorTimelineItemModal() {
    const initialState = {
      title: 'Erreur',
      list: ['Désolé, créer des éléments avant la date d\'aujourd\'hui est désactivé']
    };
    this.bsModalRef = this.modalService.show(Modal, {initialState});
    this.bsModalRef.content.onClose.subscribe(result => {
        this.createItemResult = result;
        console.log(JSON.stringify(result));
    })
  }
}

(模态组件):

export class Modal implements OnInit {

  onClose: Subject<Object>;

  constructor(
    private formBuilder: FormBuilder,
    public _bsModalRef: BsModalRef) {}

  ngOnInit(): void {
    this.onClose = new Subject();
  }

  public onConfirm(): void {
    this.onClose.next(true);
    this._bsModalRef.hide();
  }

  public onCancel(): void {
     this.onClose.next(false);
     this._bsModalRef.hide();
  }
}

如您所见,我正在从是否验证模态中得到答案。我可以控制台记录它。

现在是我被困的地方。我怎样才能让代码执行停止,直到该方法接收到一个可观察对象,以便在 if 中正确评估?

这对于正确执行我的代码实际上非常重要,因为您可能已经注意到的 callback(null);callback(item); 是完成项目创建或阻止项目创建所必需的语法.

参见:http://visjs.org/docs/timeline/#Methods

我已经使用了警报,但我正在尝试切换到功能更多、更清洁的东西。

如果我没理解错的话,你需要同步两个独立的事件。这样做通常是一种不好的做法。

尝试 re-organise 您的代码。这是一个异步进程,因此您应该将进程划分为可以单独发生的子 "transactions"。

  1. 分离打开模态的逻辑。
  2. 等待用户输入数据
  3. 处理来自模态的答案。

像这样:

  createNewTimelineItemModal() {
    const initialState = {
    ... 

    this.bsModalRef.content.onClose.subscribe(result => {
        this.createItemResult = result;
        this.continueToCreateItem(result);
      });
    }

  private continueToCreateItem(result: any){
    <insert your code here>
  }

或者其他解决方案可以是 return observable 对象并在 onAdd

中处理它
options = {
    onAdd: (item, callback) => {
    ...
          this.createNewTimelineItemModal().subscribe(result => {
             if(result is something){
              callback(item);
             } else callback(null);
         }
      }
    }
  }

对于 "halt" 来说,这个过程是一个非常糟糕的做法,但可以通过 Promise 对象来实现。

this.myPromiseReturningMethod(params).then(() => {

但这会暂时阻止您的所有应用程序(用户无法执行任何操作),因此我建议改为更改结构。