首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角9.页面上的同步*ngFor

角9.页面上的同步*ngFor
EN

Stack Overflow用户
提问于 2020-11-28 10:08:39
回答 1查看 192关注 0票数 1

因此,我收到服务器上的主题列表,然后由subject.id (从服务器)对每个主题进行摘录,并将所有主题及其摘录存储在subEx变量中(类列在下面)

代码语言:javascript
复制
  subjects:Subject[] 
  temp:Excersise[] = []
  subEx:SubjectExcersise[] = []

  constructor(private exService: ExcersiseService, private subService: SubjectService) { }

  ngOnInit(): void {
    this.getSubjects()
  }

  getSubjects(){
    let id = localStorage.getItem("id")
    this.subService.GetSubjectsBuUserId(localStorage.getItem("id")).subscribe(
      res => {
        this.subjects = res
        for (const sub of this.subjects){
          this.exService.GetExcesisesBySubject(sub.name).subscribe(
            res=>{
              this.temp = res
              this.subEx.push(new SubjectExcersise(sub, this.temp))
              console.log(this.subEx)
            }
          )
        }
      },
    )
  }

通过简单的http.get获取主题和摘录

代码语言:javascript
复制
  GetExcesisesBySubject(subName:string){
    return this.http.get<any>(this._getExcesisesBySubject+"/"+subName)
  }

然后,我将所有的主题显示为按钮,并以下拉方式添加摘录到每个按钮。

代码语言:javascript
复制
      <div class="list-group list-group-flush">
          <button *ngFor="let sub of subEx" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            {{sub.subject.name}}
            <div class="dropdown-menu">
                <a *ngFor="let ex of sub.excersises" class="dropdown-item">{{ex.title}}</a>
            </div>
          </button>
      </div>

问题是,在每个页面重新加载主题之后,主题都有不同的顺序,所有的被试都有相同的随机摘录。 (在图片上,所有主题都有"Task 1“、"Task 2”、"Task 3“)。在重新加载后,可以有2或没有)。我认为这是因为JS著名的同步/异步行为。

那么,如何使页面以相同的顺序呈现主题,以及如何为每个主题单独呈现摘录?

学科类

代码语言:javascript
复制
export class Subject
{
    constructor(id: string, name: string){
        this.Id = id
        this.name = name
    }
    Id: string
    name: string
}

选修课

代码语言:javascript
复制
import { Subject } from './Subject'

export class Excersise
{
    Id: string
    title: string
    content: string
    correctAnswer: string   
    subject: Subject 
}

SubjectExcersise类

代码语言:javascript
复制
import { Subject } from './Subject';
import { Excersise } from './Excersise';

export class SubjectExcersise{
    constructor(sub: Subject, ex: Excersise[]){
        this.subject = sub
        this.excersises = ex
    }
    subject: Subject
    excersises:Excersise[]
}

这就是GetSubjects()subEx

代码语言:javascript
复制
0: SubjectExcersise
excersises:
   0: {id: "ea9bce1d-b6bf-471e-b1df-6edb253d68e7", title: "Task2", content: "string", correctAnswer: 
   "string", subject: {…}}
   1: {id: "89121437-d01d-461b-b0a1-92b2798bd66e", title: "Task1", content: "string", correctAnswer: 
   "string", subject: {…}}
   2: {id: "3643f5db-5271-4c70-abb8-cc4a2f00d1ae", title: "Task3", content: "string", correctAnswer: 
   "string", subject: {…}}
subject: {id: "d0d20a1e-8a75-4d56-0c67-08d892dcbbe6", name: "Матан"}

1: SubjectExcersise
   excersises: []
subject:{id: "b827616b-8ee3-4dee-0c69-08d892dcbbe6", name: "Эконометрика"}

2: SubjectExcersise
excersises:
   0: {id: "955a704a-00dc-4fe0-a953-5d8dd8ce4d35", title: "Task1", content: "string", correctAnswer: 
   "string", subject: {…}}
   1: {id: "fe0dd1a7-2ee1-4948-9145-864a0b07b506", title: "Task2", content: "string", correctAnswer: 
   "string", subject: {…}}
subject: {id: "aad23a48-f04e-4114-0c68-08d892dcbbe6", name: "РИС"}
EN

回答 1

Stack Overflow用户

发布于 2020-11-28 10:46:29

实际上,您可以使用RxJS操作符为SubjectExcersise[]创建一个可观察的,并且可以使用async管道在模板中观察到。如下所示:

组件类:

代码语言:javascript
复制
  subEx$: Observable<SubjectExercise[]> = new Observable([]);
  getSubjects() {
    this.subEx$ = this.subService
      .GetSubjectsByUserId(localStorage.getItem('id'))
      .pipe(
        // Here we are automatically unsubscribing from previous subscription and
        // subscribing to next subscription i.e., `this.exService.GetExcesisesBySubject`
        switchMap((subjects) =>
          // This will only emit once each of exercises has emitted non undefined value atleast once
          combineLatest(
            // Here we are iterating over each subject and fetching the exercises
            ...subjects.map((subject) =>
              this.exService
                .GetExcesisesBySubject(subject.map)
                // Here we are creating subject exercises
                // These `SubjectExercises` will be assigned to `this.subEx$` as an observable
                .pipe((res) => new SubjectExercise(subject, res))
            )
          )
        )
      );
  }

组件模板

代码语言:javascript
复制
      <div class="list-group list-group-flush">
          <button *ngFor="let sub of subEx$ | async" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            {{sub.subject.name}}
            <div class="dropdown-menu">
                <a *ngFor="let ex of sub.excersises" class="dropdown-item">{{ex.title}}</a>
            </div>
          </button>
      </div>

希望能帮上忙。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65048442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档