Observable 需要点击加载到 html 页面
[英] Observable need a click to load on html page
本文介绍了Observable 需要点击加载到 html 页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在使用 Angular 开发 Web 应用程序,我使用 Observable
.
目前,当我搜索 firebase 数据库时,我只需创建一个 *ngFor="let myvar of _myvar |async"
和我的 HTML 页面很好地显示了数据.
但是每次 Subject
进行干预时,我的 HTML 页面都不会显示任何数据,直到我单击页面的某个元素...
这是我的代码,如果有人有想法:home.component.html
<div id="paddingTop";fxLayout=行"fxLayout.lt-md=列"fxLayoutAlign="space-around center"><div><h2>********************</h2><mat-icon>地方</mat-icon><mat-form-field color="accent"外观=填充"id=搜索地址"><mat-label>********************</mat-label><输入垫输入ngx-google-places-autocomplete #placesRef="ngx-places";(onAddressChange)="handleAddressChange($event)";/><button mat-button *ngIf="address";matSuffix mat-icon-button aria-label=清除"(点击)="地址=''"><mat-icon>关闭</mat-icon>按钮></mat-form-field>
<!--<div><mat-form-field外观=填充"颜色=口音"><mat-label>选择</mat-label><mat-select><mat-option value=one">第一个选项</mat-option><mat-option value=two">第二个选项</mat-option></mat-select></mat-form-field>
-->
<div id="searchPart"><h2>********************</h2><section class="mobile";fxLayout=列"fxLayoutAlign=居中";fxLayoutGap="20px";fxHide.lg *ngFor=让_feedersId 的id |异步"><app-feeder-card[feederId] = id"[clientId] = this.uid"></app-feeder-card></节><section *ngIf="feedersId.length == 0";fxLayout=列"fxLayoutAlign=居中";><p>********************</p><p><mat-icon>arrow_upward</mat-icon>*****************<mat-icon>arrow_upward</mat-icon></p></节>
</节>
home.component.ts
import { Component, OnInit } from '@angular/core';从@angular/fire/firestore"导入 { AngularFirestore };从@angular/router"导入{路由器};从 'rxjs' 导入 { Observable, Subject };从 'src/app/auth/auth.service' 导入 { AuthService };从'src/app/order/order.model'导入{订单};从'../user.model'导入{用户};@成分({选择器:'app-user-home',templateUrl: './user-home.component.html',styleUrls: ['./user-home.component.scss']})导出类 UserHomeComponent 实现 OnInit {订单:Observable;feedersId:数组<字符串>= [];_feedersId: Observable>= this.getFeederArray();uid:字符串;构造函数(私有路由器:路由器,私有 authService:AuthService,私有数据库:AngularFirestore){}ngOnInit(): 无效 {this.getFeederArray().subscribe(r => {console.log('测试')this.setFeederId(r);})}地址 = '';公共句柄地址更改(地址:任何){控制台日志(地址);this.address = address.formatted_address;const lat = address.geometry.location.lat();const lng = address.geometry.location.lng();const adrs = address.formatted_address;this.router.navigate(['/search-feeder/', lat, lng, adrs]);}getUser(): Observable{返回 this.authService.getUser().switchMap(user => {this.uid = user.uid;返回 this.db.collection('user').doc(user.uid).valueChanges({ idField: 'id' }) 作为 Observable;}).map(响应=> {返回响应;});}getFeederArray(): Observable>{let toReturn: Array= [];var subject = new Subject>();this.getUser().subscribe(user => {this.orders = this.db.collection(订单", ref => {返回参考.where("clientId", "==", user.id)}).valueChanges({ idField: 'id' }) 作为 Observable;this.orders.subscribe(订单=> {订单.forEach(订单=> {if(toReturn.indexOf(order.feederId) == -1) {toReturn.push(order.feederId);}})})主题.next(toReturn);})返回主题.asObservable();}setFeederId(ids: Array) {this.feedersId = ids;}}
解决方案
我简化了你的 getFeederArray
函数,返回一个 observable 而不订阅其中的两个 observable.
请您现在检查一下,然后尝试以下操作:
getFeederArray(): Observable{返回 this.getUser().pipe(switchMap((用户) => {this.orders = this.db.collection("orders", (ref) => ref.where("clientId", "==", user.id)).valueChanges({ idField: "id" }) as Observable;返回 this.orders;}),map((orders) => orders.map((order) => order.feederId)));}
I am developing a web application with Angular and I use Observable
.
Currently, when I search into the firebase DB I simply make a *ngFor="let myvar of _myvar | async"
and my HTML page well displays the data.
But every time a Subject
intervenes, my HTML page doesn't display any data until I click on an element of the page...
Here is my code, if someone has an idea :
home.component.html
<section>
<div id="paddingTop" fxLayout="row" fxLayout.lt-md="column" fxLayoutAlign="space-around center">
<div>
<h2>*****************</h2>
<mat-icon>place</mat-icon>
<mat-form-field color="accent" appearance="fill" id="searchAddress">
<mat-label>*****************</mat-label>
<input
matInput
ngx-google-places-autocomplete #placesRef="ngx-places"
(onAddressChange)="handleAddressChange($event)" />
<button mat-button *ngIf="address" matSuffix mat-icon-button aria-label="Clear" (click)="address=''">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
</div>
<!--
<div>
<mat-form-field appearance="fill" color="accent">
<mat-label>Select</mat-label>
<mat-select>
<mat-option value="one">First option</mat-option>
<mat-option value="two">Second option</mat-option>
</mat-select>
</mat-form-field>
</div>
-->
</div>
<div id="searchPart">
<h2>*****************</h2>
<section class="mobile" fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="20px" fxHide.lg *ngFor="let id of _feedersId | async">
<app-feeder-card
[feederId] = "id"
[clientId] = "this.uid"
></app-feeder-card>
</section>
<section *ngIf="feedersId.length == 0" fxLayout="column" fxLayoutAlign="center center" >
<p>*****************</p>
<p>
<mat-icon>arrow_upward</mat-icon>
*****************
<mat-icon>arrow_upward</mat-icon>
</p>
</section>
</div>
</section>
home.component.ts
import { Component, OnInit } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Router } from '@angular/router';
import { Observable, Subject } from 'rxjs';
import { AuthService } from 'src/app/auth/auth.service';
import { Order } from 'src/app/order/order.model';
import { User } from '../user.model';
@Component({
selector: 'app-user-home',
templateUrl: './user-home.component.html',
styleUrls: ['./user-home.component.scss']
})
export class UserHomeComponent implements OnInit {
orders: Observable<Order[]>;
feedersId: Array<string> = [];
_feedersId: Observable<Array<string>> = this.getFeederArray();
uid: string;
constructor(private router: Router, private authService: AuthService, private db: AngularFirestore) {}
ngOnInit(): void {
this.getFeederArray().subscribe(r => {
console.log('tests')
this.setFeederId(r);
})
}
address = '';
public handleAddressChange(address: any) {
console.log(address);
this.address = address.formatted_address;
const lat = address.geometry.location.lat();
const lng = address.geometry.location.lng();
const adrs = address.formatted_address;
this.router.navigate(['/search-feeder/', lat, lng, adrs]);
}
getUser(): Observable<User> {
return this.authService.getUser().switchMap(user => {
this.uid = user.uid;
return this.db.collection('user').doc(user.uid).valueChanges({ idField: 'id' }) as Observable<User>;
}).map(response => {
return response;
});
}
getFeederArray(): Observable<Array<string>> {
let toReturn: Array<string> = [];
var subject = new Subject<Array<string>>();
this.getUser().subscribe(user => {
this.orders = this.db.collection("orders", ref => {
return ref
.where("clientId", "==", user.id)
}).valueChanges({ idField: 'id' }) as Observable<Order[]>;
this.orders.subscribe(orders => {
orders.forEach(order => {
if(toReturn.indexOf(order.feederId) == -1) {
toReturn.push(order.feederId);
}
})
})
subject.next(toReturn);
})
return subject.asObservable();
}
setFeederId(ids: Array<string>) {
this.feedersId = ids;
}
}
解决方案
I simplified your getFeederArray
function, to return one observable without subscribing to two observables within it.
Could you please check it now, and try the following:
getFeederArray(): Observable<string[]> {
return this.getUser().pipe(
switchMap((user) => {
this.orders = this.db
.collection("orders", (ref) => ref.where("clientId", "==", user.id))
.valueChanges({ idField: "id" }) as Observable<Order[]>;
return this.orders;
}),
map((orders) => orders.map((order) => order.feederId))
);
}
这篇关于Observable 需要点击加载到 html 页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!