我正在处理一个包含多个<ion-segment>个元素的页面,其中一些元素嵌套在async个容器中. 除非对初始值进行了硬编码,否则这些值不会被正确地初始化,并且所选的<ion-segment-button>不会像它应该的那样被突出显示.

请参见下面的示例:

HTML file

<ion-header>
  <ion-toolbar>
    <ion-title>Ionic Segment Bug Test</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-segment
    [value]="segmentA$ | async"
    (ionChange)="updateSegmentA($event.detail.value!)"
  >
    <ion-segment-button value="A-1">
      <ion-label>segment A-1</ion-label>
    </ion-segment-button>
    <ion-segment-button value="A-2">
      <ion-label>segment A-2</ion-label>
    </ion-segment-button>
  </ion-segment>
  <p class="ion-text-center">segment A value = "{{ segmentA$.value }}"</p>
  <hr />
  <div *ngIf="observable$ | async as dataSource; else noData">
    <ion-segment
      [value]="segmentB"
      (ionChange)="updateSegmentB($event.detail.value!)"
    >
      <ion-segment-button value="B-1">
        <ion-label>segment B-1</ion-label>
      </ion-segment-button>
      <ion-segment-button value="B-2">
        <ion-label>segment B-2</ion-label>
      </ion-segment-button>
    </ion-segment>
    <p class="ion-text-center">segment B value = "{{ segmentB }}"</p>
    <hr />
    <ion-segment value="default">
      <ion-segment-button value="default">
        <ion-label>Default</ion-label>
      </ion-segment-button>
      <ion-segment-button value="segment">
        <ion-label>Segment</ion-label>
      </ion-segment-button>
    </ion-segment>
  </div>

  <ng-template #noData>
    <p class="ion-text-center">No data to display</p>
  </ng-template>
</ion-content>

TS file (extract)

  segmentA$ = new BehaviorSubject<string>('A-1');
  observable$ = new Observable<any>();
  segmentB = 'B-1';

  constructor() {
    this.fetchData();
  }

  updateSegmentA(value: SegmentValue) {
    this.segmentA$.next(value as string);
  }

  updateSegmentB(value: SegmentValue) {
    this.segmentB = value as string;
  }

  private fetchData() {
    let option: string;
    this.observable$ = this.segmentA$.pipe(
      distinctUntilChanged(),
      tap((o) => (option = o)),
      delay(1000),
      map(() => option),
    );
  }

请参阅GitHubStackBlitz上的完整示例.

我试着用[(ngModel)]BehaviorSubjectasync管,但都没有用.

推荐答案

看起来像是ionic 内部变量的状态引起的一些bug,作为临时解决方案,你可以使用下面的方法!

如果需要,一定要在ion GitHub页面上发布错误! 我正在手动触发更改检测,并切换[value]绑定的属性,以便组件可以检测到更改!

TS

import { AsyncPipe, CommonModule, NgIf } from '@angular/common';
import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
import { IonContent,
  IonHeader,
  IonLabel,
  IonSegment,
  IonSegmentButton,
  IonTitle,
  IonToolbar,
  SegmentValue, } from '@ionic/angular/standalone';
import { BehaviorSubject, Observable, distinctUntilChanged, tap, delay, map,finalize } from 'rxjs';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.HTML',
  styleUrls: ['home.page.scss'],
  standalone: true,
  imporTS: [AsyncPipe, IonContent, IonHeader, IonLabel, IonSegment, IonSegmentButton, IonTitle, IonToolbar, CommonModule],
})
export class HomePage {
  segmentA$ = new BehaviorSubject<string>('A-1');
  observable$ = new Observable<any>();
  segmentB = '';

  constructor(private cdr: ChangeDetectorRef) {
    this.fetchData();
  }

  updateSegmentA(value: SegmentValue) {
    this.segmentA$.next(value as string);
  }

  updateSegmentB(value: SegmentValue) {
    this.segmentB = value as string;
  }

  private fetchData() {
    let option: string;
    this.observable$ = this.segmentA$.pipe(
      distinctUntilChanged(),
      tap((o) => (option = o)),
      delay(1000),
      map(() => option),
      tap(() => {
        this.bugWorkAround();
      })
    );
  }

  bugWorkAround() {
    this.segmentB = '';
    this.cdr.markForCheck();
    setTimeout(() => {
      this.segmentB = 'B-1';
      this.cdr.markForCheck();
    })
  }
}

HTML

<ion-header>
  <ion-toolbar>
    <ion-title>Ionic Segment Bug Test</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-segment
    [value]="segmentA$ | async"
    (ionChange)="updateSegmentA($event.detail.value!)"
  >
    <ion-segment-button value="A-1">
      <ion-label>segment A-1</ion-label>
    </ion-segment-button>
    <ion-segment-button value="A-2">
      <ion-label>segment A-2</ion-label>
    </ion-segment-button>
  </ion-segment>
  <p class="ion-text-center">segment A value = "{{ segmentA$.value }}"</p>
  <hr />
  <div *ngIf="(observable$ | async) as dataSource; else noData">
    <ion-segment
      [value]="segmentB"
      (ionChange)="updateSegmentB($event.detail.value!)"
    >
      <ion-segment-button value="B-1">
        <ion-label>segment B-1</ion-label>
      </ion-segment-button>
      <ion-segment-button value="B-2">
        <ion-label>segment B-2</ion-label>
      </ion-segment-button>
    </ion-segment>
    <p class="ion-text-center">segment B value = "{{ segmentB }}"</p>
    <hr />
    <ion-segment value="default">
      <ion-segment-button value="default">
        <ion-label>Default</ion-label>
      </ion-segment-button>
      <ion-segment-button value="segment">
        <ion-label>Segment</ion-label>
      </ion-segment-button>
    </ion-segment>
  </div>

  <ng-template #noData
    ><p class="ion-text-center">No data to display</p></ng-template
  >
</ion-content>

stackblitz

Angular相关问答推荐

cat Owl carousel 位置下一个和上一个图片

如何从Angular TS文件传递$Events对象?

如何取消针叶林输入的自动填充?

如何在Angular 17中使用Angular—calendum?

第15角Cookie的单元测试用例

在Angular 多选下拉菜单中实现CDK拖放排序的问题

如何使用带有17角的Swiper 11.0.5元素

Angular NG5002错误无效的ICU消息和意外字符EOF

Router.navigate() 在功能拦截器内不起作用

如果observableA在1秒前触发,则过滤掉observableB

NX如何在前端和后端使用一个接口库

Angular UNIVERSAL prerender 错误方法 Promise.prototype.then 调用不兼容的接收器 [object Object]

在 Angular material 表单元格中渲染 html

Angular:将间隔与增量和减量相结合

Angular2 测试 - 按 ID 获取元素

使用 DomSanitizer 绕过安全性后,安全值必须使用 [property]=binding

在Angular2中获取服务的域名

Angular 2:将外部js文件导入组件

ng add 与 npm install 在 Angular 6 中的区别

Angular2动态改变CSS属性