在第二次访问路由之前,AngularFireDocument 不响应路由更改
AngularFireDocument doesn't respond to route changes before route is accessed a second time
在这个微型示例应用程序中,任何人都可以向我解释为什么 detail.component.ts
在第二次访问路由之前没有将 correct/any 数据传递给模板。第一次尝试时,组件是空白的,然后传递来自先前路由的数据。
我不明白,因为正确的 ID 被传递给 getQuote()
方法并且 valueChanges()
确实 return 一个 Observable。
所以在我看来,每次从路由器向方法传递新 ID 时,它都应该获取一个新文档。
app.service.ts
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { Quote } from './quote';
@Injectable({
providedIn: 'root'
})
export class AppService {
quote$: Observable<Quote>;
private quotesCollection: AngularFirestoreCollection<Quote> = this.afs.collection('quotes');
quotes$: Observable<Quote[]> = this.quotesCollection.valueChanges({idField: 'id'});
private quoteDocument: AngularFirestoreDocument<Quote>;
constructor(private afs: AngularFirestore) { }
getQuote(id) {
this.quoteDocument = this.quotesCollection.doc(id);
this.quote$ = this.quoteDocument.valueChanges();
}
save(quote: Quote) {
this.quotesCollection.add(quote).then(r => console.log(r));
}
delete(id: string) {
this.quotesCollection.doc(id).delete().then(r => console.log(r));
}
}
list.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AppService } from '../app.service';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ListComponent {
quotes$ = this.appService.quotes$;
constructor(private appService: AppService) { }
delete(id: string) {
this.appService.delete(id);
}
}
detail.component.ts
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AppService } from '../app.service';
@Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DetailComponent implements OnInit {
quote$ = this.appService.quote$;
constructor(private appService: AppService,
private activatedRoute: ActivatedRoute) { }
ngOnInit() {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.appService.getQuote(id);
}
}
detail.component.html
<nav>
<a [routerLink]="['/list']" routerLinkActive="active">Back to list</a>
</nav>
<div *ngIf="quote$ | async as quote">
<h1>{{quote.quote}}</h1>
</div>
您使用奇怪的方式访问 quote$
。我认为更好的是:
`
getQuote(id) {
this.quoteDocument = this.quotesCollection.doc(id);
return this.quoteDocument.valueChanges();
}
`
然后在组件处:
`
ngOnInit() {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.quote$ = this.appService.getQuote(id);
}
`
我更清楚了,我认为它解决了你的问题
在这个微型示例应用程序中,任何人都可以向我解释为什么 detail.component.ts
在第二次访问路由之前没有将 correct/any 数据传递给模板。第一次尝试时,组件是空白的,然后传递来自先前路由的数据。
我不明白,因为正确的 ID 被传递给 getQuote()
方法并且 valueChanges()
确实 return 一个 Observable。
所以在我看来,每次从路由器向方法传递新 ID 时,它都应该获取一个新文档。
app.service.ts
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { Quote } from './quote';
@Injectable({
providedIn: 'root'
})
export class AppService {
quote$: Observable<Quote>;
private quotesCollection: AngularFirestoreCollection<Quote> = this.afs.collection('quotes');
quotes$: Observable<Quote[]> = this.quotesCollection.valueChanges({idField: 'id'});
private quoteDocument: AngularFirestoreDocument<Quote>;
constructor(private afs: AngularFirestore) { }
getQuote(id) {
this.quoteDocument = this.quotesCollection.doc(id);
this.quote$ = this.quoteDocument.valueChanges();
}
save(quote: Quote) {
this.quotesCollection.add(quote).then(r => console.log(r));
}
delete(id: string) {
this.quotesCollection.doc(id).delete().then(r => console.log(r));
}
}
list.component.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AppService } from '../app.service';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ListComponent {
quotes$ = this.appService.quotes$;
constructor(private appService: AppService) { }
delete(id: string) {
this.appService.delete(id);
}
}
detail.component.ts
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AppService } from '../app.service';
@Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DetailComponent implements OnInit {
quote$ = this.appService.quote$;
constructor(private appService: AppService,
private activatedRoute: ActivatedRoute) { }
ngOnInit() {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.appService.getQuote(id);
}
}
detail.component.html
<nav>
<a [routerLink]="['/list']" routerLinkActive="active">Back to list</a>
</nav>
<div *ngIf="quote$ | async as quote">
<h1>{{quote.quote}}</h1>
</div>
您使用奇怪的方式访问 quote$
。我认为更好的是:
`
getQuote(id) {
this.quoteDocument = this.quotesCollection.doc(id);
return this.quoteDocument.valueChanges();
}
`
然后在组件处: `
ngOnInit() {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.quote$ = this.appService.getQuote(id);
}
`
我更清楚了,我认为它解决了你的问题