如何显示一个可观察到的可观察到的阵列的角度?

发布于 2025-02-03 10:31:33 字数 2440 浏览 2 评论 0原文

我有一个可观察到的阵列,其中包含一个问题列表。我想一个一个一个一个一个,但无法找到一种方法来做到这一点。

到目前为止,我只设法在我的html中使用 *ngfor显示了所有这些。

这是我的组成部分:

import { Component, OnInit } from '@angular/core';
import { mergeMap, Observable, of, concatAll, Subject, startWith, zip, Subscription } from "rxjs";
import { Question } from "../models/Question";
import { QuestionService } from "../services/question.service";
import { AuthService } from "../services/auth.service";
import { User } from "../models/User";

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

  user_id: Pick<User, "id"> | undefined
  unanswered_questions$: Observable<Question[]> | undefined
  question$: Observable<Question> | undefined

  constructor(
    private questionService: QuestionService,
    private authService: AuthService
  ) { }

  ngOnInit(): void {
    this.user_id = this.authService.userId
    this.unanswered_questions$ = this.getUnansweredQuestions(this.user_id)
  }

  getUnansweredQuestions(user_id: Pick<User, "id"> | undefined):    Observable<Question[]> {
    return this.questionService.fetchAllUnansweredQuestions(user_id);
  }
}

这是我的html:

<mat-card class="question-card" *ngFor="let question of unanswered_questions$ | async">
  <mat-card-header>
    <div mat-card-avatar class="example-header-image"></div>
    <mat-card-title>{{question.title}}</mat-card-title>
  </mat-card-header>
  <mat-card-content>
    <h3>{{question.body}}</h3>
  </mat-card-content>
  <mat-card-actions>
    <button mat-button>{{question.answer1}}</button>
    <button mat-button>{{question.answer2}}</button>
    <button mat-raised-button color="accent">Skip<mat-icon>skip_next</mat-icon></button>
  </mat-card-actions>
</mat-card>

我发现 >发布某人试图做同一件事的地方。不幸的是,该帖子上的两个答案都不适合我。我认为它们由于帖子已经4岁而无法使用,我使用了较新版本的RXJ和Angular。

任何帮助都非常感谢。谢谢你!

I have an Observable-Array which contains a list of questions. I would like to display my questions one by one but can't figure out a way to do that.

So far I only managed to display all of them with a *ngFor in my html.

This is my component:

import { Component, OnInit } from '@angular/core';
import { mergeMap, Observable, of, concatAll, Subject, startWith, zip, Subscription } from "rxjs";
import { Question } from "../models/Question";
import { QuestionService } from "../services/question.service";
import { AuthService } from "../services/auth.service";
import { User } from "../models/User";

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

  user_id: Pick<User, "id"> | undefined
  unanswered_questions$: Observable<Question[]> | undefined
  question$: Observable<Question> | undefined

  constructor(
    private questionService: QuestionService,
    private authService: AuthService
  ) { }

  ngOnInit(): void {
    this.user_id = this.authService.userId
    this.unanswered_questions$ = this.getUnansweredQuestions(this.user_id)
  }

  getUnansweredQuestions(user_id: Pick<User, "id"> | undefined):    Observable<Question[]> {
    return this.questionService.fetchAllUnansweredQuestions(user_id);
  }
}

This is my html:

<mat-card class="question-card" *ngFor="let question of unanswered_questions$ | async">
  <mat-card-header>
    <div mat-card-avatar class="example-header-image"></div>
    <mat-card-title>{{question.title}}</mat-card-title>
  </mat-card-header>
  <mat-card-content>
    <h3>{{question.body}}</h3>
  </mat-card-content>
  <mat-card-actions>
    <button mat-button>{{question.answer1}}</button>
    <button mat-button>{{question.answer2}}</button>
    <button mat-raised-button color="accent">Skip<mat-icon>skip_next</mat-icon></button>
  </mat-card-actions>
</mat-card>

I found this Post where someone is trying to do basically the same thing. Unfortunately both answers on that post don't work for me. I figured that they don't work due to the post being 4 years old and me using a newer version of rxjs and angular.

Any help is much appreciated. Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

(り薆情海 2025-02-10 10:31:34

当前,您的编码为“作品”,因为您将观察到的异步管处理程序可注入,该管道可容纳执行NGFOR,直到可观察到可观察到的解决方案为止。

我会更改您的代码,以便您订阅可观察到的代码并处理随后的结果。实际上,我首先将其转换为诺言并等待它,因为IMO,这种样式更可读性和可预测性,尤其是对于“一个人和完成”事件。

因此,更改组件这样的组件(请注意:为了简洁起见,我已经删除了进口和装饰器):

export class PlayComponent implements OnInit {

  user_id: Pick<User, "id"> | undefined;
  unanswered_questions: Question[];
  question$: Observable<Question> | undefined;
  questionIndex = 0;

  constructor(
    private questionService: QuestionService,
    private authService: AuthService
  ) { }

  async ngOnInit(): Promise<void> {
    this.user_id = this.authService.userId;
    await this.unanswered_questions = this.getUnansweredQuestions(this.user_id).toPromise();
  }

  getUnansweredQuestions(user_id: Pick<User, "id"> | undefined):    Observable<Question[]> {
    return this.questionService.fetchAllUnansweredQuestions(user_id);
  }

  skipQuestion(): void {
    if (this.questionIndex !== this.getUnansweredQuestions.length) {
     this.questionIndex++;
     }
  }
}

然后您的HTML:

<mat-card class="question-card" *ngIf="unanswered_questions">
  <mat-card-header>
    <div mat-card-avatar class="example-header-image"></div>
    <mat-card-title>{{unanswered_questions[questionIndex].title}}</mat-card-title>
  </mat-card-header>
  <mat-card-content>
    <h3>{{unanswered_questions[questionIndex].body}}</h3>
  </mat-card-content>
  <mat-card-actions>
    <button mat-button>{{unanswered_questions[questionIndex].answer1}}</button>
    <button mat-button>{{unanswered_questions[questionIndex].answer2}}</button>
    <button mat-raised-button color="accent" (click)="skipQuestion()">Skip<mat-icon>skip_next</mat-icon></button>
  </mat-card-actions>
</mat-card>

通过将NGIF添加到哑光中,您可以防止呈现渲染,直到可观察到可观察到为止。

Currently you code "works" because you are piping your observable to the async pipe handler which holds executing the ngFor until the observable is resolved.

I would alter your code so that you subscribe to the observable and handle the ensuing result. Actually, I would first convert to a promise and await it since, IMO, that style is more readable and predictable, especially for a "one and done" event.

So alter your component like so (NOTE: I've left off the imports and decorator for sake of brevity):

export class PlayComponent implements OnInit {

  user_id: Pick<User, "id"> | undefined;
  unanswered_questions: Question[];
  question$: Observable<Question> | undefined;
  questionIndex = 0;

  constructor(
    private questionService: QuestionService,
    private authService: AuthService
  ) { }

  async ngOnInit(): Promise<void> {
    this.user_id = this.authService.userId;
    await this.unanswered_questions = this.getUnansweredQuestions(this.user_id).toPromise();
  }

  getUnansweredQuestions(user_id: Pick<User, "id"> | undefined):    Observable<Question[]> {
    return this.questionService.fetchAllUnansweredQuestions(user_id);
  }

  skipQuestion(): void {
    if (this.questionIndex !== this.getUnansweredQuestions.length) {
     this.questionIndex++;
     }
  }
}

And then your HTML:

<mat-card class="question-card" *ngIf="unanswered_questions">
  <mat-card-header>
    <div mat-card-avatar class="example-header-image"></div>
    <mat-card-title>{{unanswered_questions[questionIndex].title}}</mat-card-title>
  </mat-card-header>
  <mat-card-content>
    <h3>{{unanswered_questions[questionIndex].body}}</h3>
  </mat-card-content>
  <mat-card-actions>
    <button mat-button>{{unanswered_questions[questionIndex].answer1}}</button>
    <button mat-button>{{unanswered_questions[questionIndex].answer2}}</button>
    <button mat-raised-button color="accent" (click)="skipQuestion()">Skip<mat-icon>skip_next</mat-icon></button>
  </mat-card-actions>
</mat-card>

By adding ngIf to your matCard you prevent rendering until the observable is resolved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文