簡體   English   中英

如何等到 post 方法完成 Angular

[英]How to wait until post method finished Angular

我正在開發知識測試系統,因此作為管理員,我可以創建測試。 在我創建測試的頁面上,首先我輸入有關測試和問題計數的信息。 然后對於每個問題,我都會輸入該問題的答案計數和有關問題的信息。 然后對於每個答案,我都會輸入一些信息,然后單擊提交按鈕。

動作順序必須如下:

發布測試->發布第一個問題->發布第一個問題的答案->發布第二個問題等。

所以我需要等到第一個問題被創建,然后為這個問題創建每個答案,然后才為它創建第二個問題和答案。

順序非常重要,必須像我寫的那樣。

但我有一個錯誤,我的訂單沒有按我想要的方式工作,因為我的 post 方法是異步工作的。

例如,如果我為每個問題創建 2 個問題和 2 個答案,我的訂單將變為:

發布測試完成 -> 發布問題 2 完成 -> 發布問題 1 完成 -> 發布所有答案完成

所以我需要知道,如何等到 post 方法完成。

這是我為他們發布問題和答案的方法:

for(let item of this.sas){// sas is type Map<Question, Answer[]>
      // get question info
      let q = document.getElementById(`q_${ii+1}`) as HTMLInputElement;
      let t = document.getElementById(`t_${ii+1}`) as HTMLInputElement;
      let isSin = true;
      if(t.checked){
        isSin = false;
      }
      let question = new Question();
      question.Content = q.value;
      question.IsSingle = isSin;
      //

      // get answers for this question
      let answers = [];
      for(let j of item[1]){
        let isCorrect = document.getElementById(`a_isCorrect_${ii}:${j}`) as unknown as HTMLInputElement;
        let content = document.getElementById(`a_content_${ii}:${j}`) as unknown as HTMLInputElement;
        let mark =  document.getElementById(`a_mark_${ii}:${j}`) as unknown as HTMLInputElement;

        let answer = new Answer();
        answer.IsCorrect = isCorrect.checked;
        answer.Content = content.value;
        answer.Mark = Number(mark.value);
        answers.push(answer);
        j++;
      }

      //post question
      this.questionService.createQuestion(question).subscribe(data=> {
        console.log(`question ${question.Content} done`);
      //

         //post answers for question
           from(answers).pipe(
             map(answer => this.answerService.createAnswer(answer).subscribe(data => { 
                          console.log(`answer ${answer} done` ) } ) )
           ).subscribe(s=> { console.log("done")});
      //
      });
      ii++;
    };
  }

我相信你最好的選擇,只要你不需要 POST A BUNCH ,可能是這樣的遞歸:

function handleQuestion(item, index = 0) {
let q = document.getElementById(`q_${index+1}`) as HTMLInputElement;
let t = document.getElementById(`t_${index+1}`) as HTMLInputElement;
let isSin = true;
if(t.checked){
    isSin = false;
}
let question = new Question();
question.Content = q.value;
question.IsSingle = isSin;

let answers = [];
for(let j of item){
    let isCorrect = document.getElementById(`a_isCorrect_${index}:${j}`) as unknown as HTMLInputElement;
    let content = document.getElementById(`a_content_${index}:${j}`) as unknown as HTMLInputElement;
    let mark =  document.getElementById(`a_mark_${index}:${j}`) as unknown as HTMLInputElement;

    let answer = new Answer();
    answer.IsCorrect = isCorrect.checked;
    answer.Content = content.value;
    answer.Mark = Number(mark.value);
    answers.push(answer);
    j++;
}

this.questionService.createQuestion(question).subscribe(data=> {
    from(answers).pipe(
    map(answer => this.answerService.createAnswer(answer).subscribe(data => { 
        console.log(`answer ${answer} done` ) } ) )
    ).subscribe(s=> {
        index++;
        if (this.sas[index]) {
            handleQuestion(this.sas[index], index);
        }
    });
}); }

您可以結合兩個 observables... 以在兩者都已經響應時獲得響應數據。

fetchData(): Observable<any[]> {
    return combineLatest(
        this.observable1$(),
        this.observable2$()
    );
}

你需要在這里使用concatMap ,它會逐步等待每次發射。

//post question
this.questionService.createQuestion(question).pipe(
    // executes answers only when question emits.
    concatMap(data=> {
        console.log(`question ${question.Content} done`);
        //

        //post answers for question
        return from(answers).pipe(
            concatMap(answer => this.answerService.createAnswer(answer).pipe(
                tap(data => console.log(`answer ${answer} done` ) ),
            )),
            finalize(() => console.log("done")),
        );
    }),
).subscribe();

如果你想要整件事:

let ii = 0;
from(this.sas).pipe(
    contactMap(item => {
        // get question info
        let q = document.getElementById(`q_${ii+1}`) as HTMLInputElement;
        let t = document.getElementById(`t_${ii+1}`) as HTMLInputElement;
        let isSin = true;
        if(t.checked){
            isSin = false;
        }
        let question = new Question();
        question.Content = q.value;
        question.IsSingle = isSin;
        //

        // get answers for this question
        let answers = [];
        for(let j of item[1]){
            let isCorrect = document.getElementById(`a_isCorrect_${ii}:${j}`) as unknown as HTMLInputElement;
            let content = document.getElementById(`a_content_${ii}:${j}`) as unknown as HTMLInputElement;
            let mark =  document.getElementById(`a_mark_${ii}:${j}`) as unknown as HTMLInputElement;

            let answer = new Answer();
            answer.IsCorrect = isCorrect.checked;
            answer.Content = content.value;
            answer.Mark = Number(mark.value);
            answers.push(answer);
            j++;
        }
        ii++;

        //post question
        return this.questionService.createQuestion(question).pipe(
            // executes answers only when question emits.
            concatMap(data=> {
                console.log(`question ${question.Content} done`);
                //

                //post answers for question
                return from(answers).pipe(
                    concatMap(answer => this.answerService.createAnswer(answer).pipe(
                        tap(data => console.log(`answer ${answer} done` ) ),
                    )),
                    finalize(() => {
                        console.log("done");
                    ),
                );
            }),
        );
    }),
    finalize(() => {
      // call done function here.
    ),
).subscribe();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM