如何访问可观察列表中的对象 [英] How to access the object in the observable list

查看:108
本文介绍了如何访问可观察列表中的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建测验应用程序.我的想法是每页显示1个问题.如何使用Observable订阅并在列表中获取对象.

I'm building a quiz app. My idea is to show 1 question per page. How do I subscribe and get an object inside a list using Observable.

代替使用显示我所有对象的 * ngFor .有没有一种方法可以在 subscribe 块中逐个访问对象.

Instead of using *ngFor which display all of my objects. Is there a way to access the object one by one inside the subscribe block.

export class ExerciseFlashcardPage {


  questions: Observable < any > ;
  type: string;

  constructor(
    public navCtrl: NavController, 
    public navParams: NavParams, 
    public afd: AngularFireDatabase
  ) {
    this.type = this.navParams.get('data');
    this.questions = this.afd.list('exercises/' + this.type).valueChanges();
    this.questions.subscribe(e => {
      console.log(e); // how to access the data //only returns an array of object
    })

  }
}

这是模板:

<ion-header>
  <ion-navbar>
    <ion-title>exercise-flashcard</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list>
    <ion-item *ngFor="let item of questions | async">
      {{item.question}}
    </ion-item>
  </ion-list>
</ion-content>

推荐答案

首先,您的实现存在问题:

在您的 ExerciseFlashcardPage 中,您正在订阅 Observable ,它将对其进行解包.但是,然后您还在模板中使用 async 管道,该管道将期望 Promise Observable .

In your ExerciseFlashcardPage, you're subscribing to the Observable which will unwrap it. But then you're also using the async pipe in your template which will be expecting a Promise or an Observable.

只需从代码中删除订阅行即可:

Just remove the subscription line from your code:

// Remove this part
this.questions.subscribe(e => {
  console.log(e); // how to access the data //only returns an array of object
});

这样,您也不必担心在该组件被销毁后手动取消订阅.

That way you also won't have to worry about manually unsubscribing from the subscription when this component is destroyed.

现在针对您的特定用例,如何处理订阅都无关紧要.您所需要的只是一次显示一个问题.为此,您只需在组件类上保留一个 currentQuestion 属性,然后将 * ngFor [ngClass]

Now for your specific use-case, it doesn't matter how you handle the subscription. All you need is to show one question at a time. For that, you can just keep a currentQuestion property on your Component Class and then use *ngFor along with [ngClass]

然后,当用户提交一个问题时,您可以将 currentQuestion 属性增加1.

And then when the user submits one question, you can increment the currentQuestion property by 1.

在代码中,这看起来像:

In code, this would look something like:

import { map } from 'rxjs/operators';

export class ExerciseFlashcardPage {

  questions: Observable < any > ;
  type: string;

  constructor(
    public navCtrl: NavController, 
    public navParams: NavParams, 
    public afd: AngularFireDatabase
  ) { }
  

  ngOnInit() {
    this.type = this.navParams.get('data');
    this.questions = this.afd.list('exercises/' + this.type).valueChanges()
      // The below Pipe operation is not required if you don't plan to change the data-model of the question object.
      .pipe(map(questions => {
        return questions.map(question => {
          return {
            ...question,
            yourNewKeyHere: 'Value to that new key here'
          }
        });
      }));
  }

  submitCurrentQuestion() {
    // Make changes to save the answer
    
    ++this.currentQuestion;
  }

}

在模板中:

<ion-header>
  <ion-navbar>
    <ion-title>exercise-flashcard</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list>
    <ion-item 
      *ngFor="let item of questions | async; let i = index;" 
      [ngClass]="(i === currentQuestion) ? '': 'hide'">
      {{item.question}}
    </ion-item>
  </ion-list>
</ion-content>

CSS:

.hide {
  display: none;
}

这是一个 样本StackBlitz 供您参考.

Here's a Sample StackBlitz for your ref.

这篇关于如何访问可观察列表中的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆