简体   繁体   English

Angular 更改检测未在初始导航的延迟加载页面上发生

[英]Angular Change Detection not happening on Lazy loaded pages on initial navigation

I am currently using Angular 13 and Ionic v6 with AngularFire v7.我目前正在使用 Angular 13 和 Ionic v6 以及 AngularFire v7。

After logging in to the application with firebase authentication.使用 firebase 身份验证登录应用程序后。 I navigate the user to the lazy-loaded home page.我将用户导航到延迟加载的主页。 In the background, I retrieve some required company data and share them through the service using a behaviour subject.在后台,我检索了一些所需的公司数据,并使用行为主题通过服务共享它们。 If the user has never logged in before the page gets stuck on loading.如果用户在页面卡在加载之前从未登录过。

If I resize the window the content appears or if I navigate away and come back the content appears.如果我调整 window 的大小,内容就会出现,或者如果我离开并返回,内容就会出现。 This happens with each lazy-loaded page after initial login.在初始登录后,每个延迟加载的页面都会发生这种情况。 I use the async pipe to access the observables so all that is managed by angular.我使用异步 pipe 来访问可观察对象,因此所有这些都由 angular 管理。

I have tried to manually detect changes and tried multiple versions of observables and strategies but nothing works.我曾尝试手动检测更改并尝试了多个版本的可观察对象和策略,但没有任何效果。

Here is a demo of the issue这是问题的演示

Ts file文件

import { Component, OnInit } from '@angular/core';
import { IonRouterOutlet } from '@ionic/angular';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { AddEstimatePage } from './add-estimate/add-estimate.component';
import { Company } from '../models/company.model';
import { MasterService } from '../services/master.service';
import { Estimate } from '../models/estimate.model';
@Component({
  selector: 'app-estimates',
  templateUrl: './estimates.page.html',
})
export class EstimatesPage implements OnInit {
  estimates$: Observable<Estimate[] | any>;
  company$: Observable<Company>;
  user$: Observable<any>;
  isLoading = true;
  constructor(private masterSvc: MasterService) {
    this.company$ = this.masterSvc.auth().company$;
    this.user$ = this.masterSvc.auth().user$;
  }

  ngOnInit() {
    this.init();
  }

  async editEstimate(
    estimate: Estimate,
    data: { company: Company; user: any }
  ) {
    const modal = await this.masterSvc.modal().create({
      component: AddEstimatePage,
      componentProps: {
        company: data.company,
        user: data.user,
        estimate,
        isEdit: true,
      },
      showBackdrop: false,
      id: 'editEstimate',
      cssClass: 'fullscreen',
    });
    return await modal.present();
  }

  async addEstimate(data: { company: Company; user: any }) {
    const modal = await this.masterSvc.modal().create({
      component: AddEstimatePage,
      componentProps: {
        company: data.company,
        user: data.user,
      },
      cssClass: 'fullscreen',
      showBackdrop: false,
      id: 'addEstimate',
    });
    return await modal.present();
  }

  init() {
    this.estimates$ = this.company$.pipe(
      switchMap((company) => {
        if (company) {
          return this.masterSvc
            .edit()
            .getDocsByCompanyIdOrdered(
              `company/${company.id}/estimates`,
              'date',
              'desc'
            );
        } else {
          return of(false);
        }
      })
    ) as Observable<any>;
  }
}

html file html 文件

<app-header title="Estimates" btnName="refresh" (updated)="init()"></app-header>
<ion-content fullscreen="true">
  <app-header-condensed title="Estimates"></app-header-condensed>
  <ng-container *ngIf="{company: company$ |async, user: user$ | async} as data">
    <app-estimate-table
      [value]="estimates$"
      *ngIf="estimates$ | async else loading"
      (selectedItem)="editEstimate($event,data)"
    ></app-estimate-table>

    <ion-fab class="m-2" vertical="bottom" horizontal="end" slot="fixed">
      <ion-fab-button (click)="addEstimate(data)">
        <ion-icon name="add"></ion-icon>
      </ion-fab-button>
    </ion-fab>
    <ng-template #loading>
      <div class="ion-padding">
        <app-skeleton-text></app-skeleton-text>
        <app-skeleton-text></app-skeleton-text>
        <app-skeleton-text></app-skeleton-text>
        <app-skeleton-text></app-skeleton-text>
      </div>
    </ng-template>
  </ng-container>
</ion-content>

Update更新

I got it working with the following.我得到它与以下工作。 It's a bit questionable but it works:)这有点可疑,但它有效:)

Ts file文件

import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { Observable, of, timer } from 'rxjs';
import { concatMap, filter, switchMap, tap } from 'rxjs/operators';
import { SiteFormComponent } from '../components/site-form/site-form.component';
import { AddEstimatePage } from '../estimates/add-estimate/add-estimate.component';
import { Company } from '../models/company.model';
import { Estimate } from '../models/estimate.model';
import { Site } from '../models/site.model';
import { MasterService } from '../services/master.service';
import { AddSiteComponent } from './add-site/add-site.component';

@Component({
  selector: 'app-sites',
  templateUrl: './sites.page.html',
})
export class SitesPage implements OnInit {
  sites$: Observable<Site[] | any>;
  company$: Observable<Company>;
  user$: Observable<any>;
  isLoading = true;
  constructor(
    private masterSvc: MasterService,
    private change: ChangeDetectorRef
  ) {
    this.company$ = this.masterSvc.auth().company$;
    this.user$ = this.masterSvc.auth().user$;
  }

  ngOnInit() {
    this.init();
  }

  async viewSite(siteData: Site, data: { company: Company; user: any }) {
    const modal = await this.masterSvc.modal().create({
      component: AddSiteComponent,
      componentProps: {
        company: data.company,
        user: data.user,
        siteData,
        isEdit: true,
      },
      showBackdrop: false,
      id: 'editSite',
      cssClass: 'fullscreen',
    });
    return await modal.present();
  }

  async addSite(data: { company: Company; user: any }) {
    const modal = await this.masterSvc.modal().create({
      component: AddSiteComponent,
      componentProps: {
        company: data.company,
        user: data.user,
        isCreate: true,
      },
      cssClass: 'fullscreen',
      showBackdrop: false,
      id: 'addSite',
    });
    return await modal.present();
  }

  init() {
    this.sites$ = this.company$.pipe(
      switchMap((company) => {
        if (company) {
          return this.masterSvc
            .edit()
            .getDocsByCompanyIdOrdered(
              `company/${company.id}/sites`,
              'code',
              'desc'
            )
            .pipe(
              tap(() => {
                this.isLoading = false;
                this.change.detectChanges();
              })
            );
        } else {
          return timer(1);
        }
      })
    ) as Observable<any>;
  }
}

html file html 文件

<app-header title="Sites" btnName="refresh" (updated)="init()"></app-header>
<ion-content fullscreen="true">
  <app-header-condensed title="Sites"></app-header-condensed>
  <ng-container
    *ngIf="{company: company$ |async, user: user$ | async,sites: sites$ | async} as data"
  >
    <app-site-table
      [value]="sites$"
      *ngIf="!isLoading else loading"
      (selectedItem)="viewSite($event,data)"
    ></app-site-table>

    <ion-fab class="m-2" vertical="bottom" horizontal="end" slot="fixed">
      <ion-fab-button (click)="addSite(data)">
        <ion-icon name="add"></ion-icon>
      </ion-fab-button>
    </ion-fab>
    <ng-template #loading>
      <div class="ion-padding">
        <app-skeleton-text></app-skeleton-text>
        <app-skeleton-text></app-skeleton-text>
        <app-skeleton-text></app-skeleton-text>
        <app-skeleton-text></app-skeleton-text>
      </div>
    </ng-template>
  </ng-container>
</ion-content>

Yesterday I have handled this problem and you can find a complete description on github.com/ionic-team昨天我已经处理了这个问题,你可以在github.com/ionic-team上找到完整的描述

Resume: There was a bug in @ionic/angular and you have to update it:简历:@ionic/angular 有一个错误,你必须更新它:

npm i @ionic/angular@latest

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何修复在三元导航返回中呈现的两个页面 - How fix two pages render in ternary navigation return 已部署 angular 8 应用在初始路由 URL 上出现错误 - Deployed angular 8 app gets an error on initial route urls 如何在运行函数之前等待数据从 Firestore 加载 Angular - How to wait for data to be loaded from Firestore before running functions Angular 调解 Class Mediator 没有发生 - Mediation of Class Mediator not happening Google Cloud Vision API - DOCUMENT_TEXT_DETECTION:“页面”中没有“属性”字段 - Google Cloud Vision API - DOCUMENT_TEXT_DETECTION: no "property" field in "pages" 区分vue导航守卫中的路由更改和页面刷新? - Differentiate between route change and page refresh in vue navigation guard? SVG 页面没有加载图片 - SVG images are not loaded on the page 当 EC2 实例终止时,EBS Volume 发生了什么? - What's happening with EBS Volume when an EC2 instance is terminated? Angular 通用构建 baseHref 更改中断应用程序中的路由 angular - Angular universal build baseHref change breaks angular routing in app Lambda 查询 Redshift:没有任何反应 - Lambda querying Redshift: Nothing Happening
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM