我正在构建测验应用程序。我的想法是每页显示1个问题。如何使用Observable订阅并在列表中获取对象。
代替使用*ngFor
来显示我所有的对象。有没有一种方法可以在subscribe
块中逐个访问对象。
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>
答案 0 :(得分:1)
首先,您的实现存在问题:
在您的ExerciseFlashcardPage
中,您正在订阅Observable
,它将解开它。但是,然后您还在模板中使用async
管道,因此期望使用Promise
或Observable
。
只需从代码中删除订阅行即可:
// Remove this part
this.questions.subscribe(e => {
console.log(e); // how to access the data //only returns an array of object
});
这样,您也不必担心在销毁该组件时手动取消订阅。
现在针对您的特定用例,如何处理订阅都无关紧要。您只需要一次显示一个问题。为此,您只需在组件类上保留currentQuestion
属性,然后将*ngFor
与[ngClass]
然后,当用户提交一个问题时,您可以将currentQuestion
属性增加1。
在代码中,这类似于:
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;
}
这是您推荐的Sample StackBlitz。
答案 1 :(得分:0)
.subscribe(arr => {
arr.forEach(item => {
console.log(item)
})
})
或更改项目:
.subscribe(arr => {
this.arr = arr.map(item => {
item.something = 'somevalue'
console.log(item)
return item
})
})
答案 2 :(得分:0)
我假设您希望拥有整个数组,并且在各种情况下仅使用特定元素,而无需再次订阅。
question: string;
questionsArray: Array<any>
elementToShow = 0; //whichever element you want to show
this.questions.subscribe(e => {
questionsArray = e;
});
使用html:
<ion-list>
<ion-item>
{{questionsArray[elementToShow]}}
</ion-item>
</ion-list>
如果您确实要预订数组的一个元素,它将看起来像这样:
question: string;
elementToShow = 0; //whichever element you want to show
this.questions.subscribe(e => {
question = e[elementToShow];
}
使用html:
<ion-list>
<ion-item>
{{question}}
</ion-item>
</ion-list>
订阅Observables是异步的,因此请注意,只有在subscription方法结束后,它才会以您想要的方式显示。执行订阅后,将对其进行更新。在这样一个简单的示例中,您不必为此担心很多。