Observable 需要点击加载到 html 页面 [英] Observable need a click to load on html page

查看:30
本文介绍了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屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆