这是导致问题的行为。 https://media.giphy.com/media/1o1oEgsCSoV9wYcTx2/source.mp4当我从段返回导航时,值消失。
价值是第一次来,但它不会留下来。我也看到有时observable需要花费大量时间来显示或获取值。
这是我的ts文件
import { AngularFireAuth } from 'angularfire2/auth';
import { SettingsPage } from './../settings/settings';
import { TranslateService } from '@ngx-translate/core';
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { IonicPage, NavController, NavParams, ModalController, AlertController } from 'ionic-angular';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import * as firebase from 'firebase';
import { FirestoreService } from './../../services/firestore.service';
/**
* Generated class for the ProfileMasterPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
@IonicPage()
@Component({
selector: 'page-profile-master',
templateUrl: 'profile-master.html'
})
export class ProfileMasterPage {
myuid;
userRef: AngularFirestoreDocument<any> ;
details: string = "Info";
phoneNumbers: Observable<any[]>;
email: Observable<any[]>;
web: Observable<any[]>;
address: Observable<any[]>;
mypr: Observable<any>;
constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController, public modalCtrl: ModalController, public translateService: TranslateService, private afAuth: AngularFireAuth, private fs: FirestoreService) {
this.myuid = this.afAuth.authState.subscribe(result => {this.myuid = result.uid});
this.translateService.get('DELETE_BUTTON');
}
ngOnInit(){
this.userRef = this.fs.doc(`users/${this.myuid}`);
console.log('userRef', this.userRef);
//this.mypr = userRef.valueChanges();
this.mypr = this.fs.doc$(this.userRef);
this.phoneNumbers = this.fs.colWithIds$(this.userRef.collection('phoneNumbers'));
this.email = this.fs.colWithIds$(this.userRef.collection('email'));
this.web = this.fs.colWithIds$(this.userRef.collection('website'));
this.address = this.fs.colWithIds$(this.userRef.collection('address'));
}
firestore服务返回此信息
import { Injectable } from '@angular/core';
import { AngularFirestore,
AngularFirestoreCollection,
AngularFirestoreDocument
} from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/switchMap';
import * as firebase from 'firebase/app';
type CollectionPredicate<T> = string | AngularFirestoreCollection<T>;
type DocPredicate<T> = string | AngularFirestoreDocument<T>;
@Injectable()
export class FirestoreService {
constructor(public afs: AngularFirestore) { }
/// **************
/// Get a Reference
/// **************
col<T>(ref: CollectionPredicate<T>, queryFn?): AngularFirestoreCollection<T> {
return typeof ref === 'string' ? this.afs.collection<T>(ref, queryFn) : ref
}
doc<T>(ref: DocPredicate<T>): AngularFirestoreDocument<T> {
return typeof ref === 'string' ? this.afs.doc<T>(ref) : ref
}
/// **************
/// Get Data
/// **************
doc$<T>(ref: DocPredicate<T>): Observable<T> {
return this.doc(ref).snapshotChanges().map(doc => {
return doc.payload.data() as T
})
}
col$<T>(ref: CollectionPredicate<T>, queryFn?): Observable<T[]> {
return this.col(ref, queryFn).snapshotChanges().map(docs => {
return docs.map(a => a.payload.doc.data()) as T[]
});
}
/// with Ids
colWithIds$<T>(ref: CollectionPredicate<T>, queryFn?): Observable<any[]> {
return this.col(ref, queryFn).snapshotChanges().map(actions => {
return actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
});
});
}
最后我的HTML看起来像这样
<ion-content>
<div>
<ion-card>
<ion-img width="75" height="75" src="./../../assets/img/nin-live.png "></ion-img>
<ion-card-content>
<button ion-button icon-left (click)="mainEdit()">
<ion-icon name="person"></ion-icon>
</button>
<ion-card-title>
{{ (mypr | async)?.displayName }}
</ion-card-title>
<h2>
{{ (mypr | async)?.title }}
</h2>
<p padding>
{{ (mypr | async)?.company }}
</p>
<ion-item>{{ (mypr | async)?.city }} </ion-item>
<ion-item>{{ (mypr | async)?.country }} </ion-item>
</ion-card-content>
</ion-card>
<ion-segment [(ngModel)]="details">
<ion-segment-button value="Info">
Card
</ion-segment-button>
<ion-segment-button value="Details">
Details
</ion-segment-button>
</ion-segment>
<div [ngSwitch]="details">
<ion-list *ngSwitchCase="'Info'">
<ion-item>
<ion-icon name="call" item-start></ion-icon>
{{ (mypr | async)?.phnumber }}
</ion-item>
<ion-item>
<ion-icon name="mail" item-start></ion-icon>
{{ (mypr | async)?.email }}
</ion-item>
<ion-item>
<ion-icon name="link" item-start></ion-icon>
{{ (mypr | async)?.website }}
</ion-item>
</ion-list>
<ion-list *ngSwitchCase="'Details'">
<ion-list-header>
Phone Numbers
</ion-list-header>
<ion-item-sliding *ngFor="let ph of phoneNumbers | async ">
<button ion-item (click)="upsert(ph,'phoneNumber')">
<ion-col>
<h3>{{ ph.type }}:</h3>
</ion-col>
<ion-col>
<p>{{ ph.phNumber }}</p>
</ion-col>
</button>
<ion-item-options>
<button ion-button color="danger" (click)="delete( ph, 'phoneNumber')">
{{ 'DELETE_BUTTON' | translate }}
</button>
</ion-item-options>
</ion-item-sliding>
<ion-item>
<ion-icon name="add" item-start></ion-icon>
<button ion-button color="primary" (click)="upsert(ph=null, 'phoneNumber')">
add More..
</button>
</ion-item>
编辑我的html只使用2个异步管道
<ion-icon name="person"></ion-icon>
</button>
<div *ngIf="mypr | async as user">
<ion-card-title>
{{ user.displayName }}
</ion-card-title>
<h2>
{{ user.title }}
</h2>
<p padding>
{{ user.company }}
</p>
<ion-item>{{ user.city }} </ion-item>
<ion-item>{{ user.country }} </ion-item>
</div>
</ion-card-content>
</ion-card>
<ion-segment [(ngModel)]="details">
<ion-segment-button value="Info">
Card
</ion-segment-button>
<ion-segment-button value="Details">
Details
</ion-segment-button>
</ion-segment>
<div [ngSwitch]="details">
<ion-list *ngSwitchCase="'Info'">
<div *ngIf="mypr | async as user">
<ion-item>
<ion-icon name="call" item-start></ion-icon>
{{ user.phnumber }}
</ion-item>
<ion-item>
<ion-icon name="mail" item-start></ion-icon>
{{ user.email }}
</ion-item>
<ion-item>
<ion-icon name="link" item-start></ion-icon>
{{ user.website }}
</ion-item>
</div>
</ion-list>
尝试将异步管道移动到选项卡之外,如下所示:
<!-- this should wrap the whole template -->
<ng-container *ngIf="mypr | async as user">
<!-- some other code of the app -->
<ion-icon name="person"></ion-icon>
</button>
<div>
<ion-card-title>
{{ user.displayName }}
</ion-card-title>
<h2>
{{ user.title }}
</h2>
<p padding>
{{ user.company }}
</p>
<ion-item>{{ user.city }} </ion-item>
<ion-item>{{ user.country }} </ion-item>
</div>
</ion-card-content>
</ion-card>
<ion-segment [(ngModel)]="details">
<ion-segment-button value="Info">
Card
</ion-segment-button>
<ion-segment-button value="Details">
Details
</ion-segment-button>
</ion-segment>
<div [ngSwitch]="details">
<ion-list *ngSwitchCase="'Info'">
<div>
<ion-item>
<ion-icon name="call" item-start></ion-icon>
{{ user.phnumber }}
</ion-item>
<ion-item>
<ion-icon name="mail" item-start></ion-icon>
{{ user.email }}
</ion-item>
<ion-item>
<ion-icon name="link" item-start></ion-icon>
{{ user.website }}
</ion-item>
</div>
</ion-list>
</ng-container>