Я начал получать предупреждение пассивного слушателя событий в форме, используемой в проекте ioni c. Я воспроизвел его, используя простой вкладок ioni c tabs и установил следующие версии ioni c, angular и конденсатор:
Ioni c:
Ioni c CLI: 6.4.0 (/usr/local/lib/node_modules/@ionic/cli).
Ioni c Framework: @ ionic / angular 5.0.7.
@ angular -devkit / build- angular: 0.803.26.
@ angular -devkit / schematics: 8.3.26.
@ angular / cli: 8.3.26.
@ ionic / angular -toolkit: 2.2.0.
Конденсатор:
Конденсатор CLI: 2.0.1.
@ конденсатор / сердечник: 2.0.1.
В Google Chrome это появляется только тогда, когда я установил устройство на 'iOS'. Существует заметная задержка между нажатием на поле ионного ввода и полем, доступным для ввода данных. Это сохраняется, когда я компилирую код и упаковываю его как приложение iOS. Настройка устройства как устройства android в Google Chrome и компиляция приложения Android не затрагиваются.
Чтобы воспроизвести эту проблему, создайте новое приложение вкладок ioni c и замените файлы tab1 со следующим:
tab1.module.ts
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { Tab1Page } from './tab1.page';
import { ExploreContainerComponentModule } from '../explore-container/explore-container.module';
@NgModule({
imports: [
IonicModule,
CommonModule,
ReactiveFormsModule,
ExploreContainerComponentModule,
RouterModule.forChild([{ path: '', component: Tab1Page }])
],
declarations: [Tab1Page]
})
export class Tab1PageModule {}
tab1.page. html
<ion-toolbar color="primary">
<ion-title>
Calculate Score
</ion-title>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs/tab2"></ion-back-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<form [formGroup]="batsForm" (ngSubmit)="submitForm()" novalidate>
<!-- Inputs with labels -->
<ion-item>
<ion-label position="fixed">Age </ion-label>
<ion-input formControlName="age" type="number" pattern="[0-9]*" placeholder="Enter age"></ion-input>
<ion-select formControlName="period" value="years" okText="Select" cancelText="Cancel">
<ion-select-option value="years">Years</ion-select-option>
<ion-select-option value="months">Months</ion-select-option>
</ion-select>
<!-- <ion-input (click)="showPicker()" value="{{ age }} {{ period }}"></ion-input> -->
</ion-item>
<ion-item *ngIf="batsForm.get('age').dirty && errorControl.age.invalid">
<ion-text color="danger" *ngIf="batsForm.get('age').dirty && errorControl.age.errors?.min">
Age must be greater than 0
</ion-text>
<ion-text color="danger" *ngIf="batsForm.get('age').dirty && errorControl.age.errors?.max">
Age must be less than 116
</ion-text>
<ion-text color="danger"*ngIf="batsForm.get('age').dirty && errorControl.age.errors?.required">
An age value is required
</ion-text>
</ion-item>
<ion-radio-group formControlName="penetrating" >
<ion-list-header>
<ion-label>Penetrating injury</ion-label>
</ion-list-header>
<ion-item>
<ion-label>Yes</ion-label>
<ion-radio slot="start" value="yes"></ion-radio>
</ion-item>
<ion-item>
<ion-label>No</ion-label>
<ion-radio slot="start" value="no" checked></ion-radio>
</ion-item>
</ion-radio-group>
<ion-radio-group formControlName="velocity" >
<ion-list-header>
<ion-label>High velocity trauma</ion-label>
</ion-list-header>
<ion-item>
<ion-label>Yes</ion-label>
<ion-radio slot="start" value="yes"></ion-radio>
</ion-item>
<ion-item>
<ion-label>No</ion-label>
<ion-radio slot="start" value="no" checked></ion-radio>
</ion-item>
</ion-radio-group>
<ion-item>
<ion-label position="fixed">Systolic BP</ion-label>
<ion-input formControlName="bp" type="number" pattern="[0-9]*" min="0" max="240" required></ion-input>
</ion-item>
<ion-item *ngIf="batsForm.get('bp').dirty && errorControl.bp.invalid">
<ion-text color="danger" *ngIf="batsForm.get('bp').dirty && errorControl.bp.errors?.min">
BP must be greater than 0mmHg
</ion-text>
<ion-text color="danger" *ngIf="batsForm.get('bp').dirty && errorControl.bp.errors?.max">
BP must be less than 240mmHg
</ion-text>
<ion-text color="danger"*ngIf="batsForm.get('bp').dirty && errorControl.bp.errors?.required">
Blood pressure value is required
</ion-text>
</ion-item>
<ion-item>
<ion-label position="fixed">GCS</ion-label>
<ion-input formControlName="gcs" type="number" pattern="[0-9]*" min="3" max="15" required></ion-input>
</ion-item>
<ion-item *ngIf="batsForm.get('gcs').dirty && errorControl.gcs.invalid">
<ion-text color="danger" *ngIf="batsForm.get('gcs').dirty && errorControl.gcs.errors?.min">
GCS must be 3 or more
</ion-text>
<ion-text color="danger" *ngIf="batsForm.get('gcs').dirty && errorControl.gcs.errors?.max">
GCS must be 15 or less
</ion-text>
<ion-text color="danger"*ngIf="batsForm.get('gcs').dirty && errorControl.gcs.errors?.required">
A GCS is required
</ion-text>
</ion-item>
<ion-item>
<ion-label position="fixed">Resp Rate</ion-label>
<ion-input formControlName="rr" type="number" pattern="[0-9]*" min="0" max="60" required></ion-input>
</ion-item>
<ion-item *ngIf="batsForm.get('rr').dirty && errorControl.rr.invalid">
<ion-text color="danger" *ngIf="batsForm.get('rr').dirty && errorControl.rr.errors?.min">
Resp rate must be greater than 0
</ion-text>
<ion-text color="danger" *ngIf="batsForm.get('rr').dirty && errorControl.rr.errors?.max">
Resp rate must be less than 60
</ion-text>
<ion-text color="danger"*ngIf="batsForm.get('rr').dirty && errorControl.rr.errors?.required">
A respiratory rate is required
</ion-text>
</ion-item>
<ion-item>
<ion-label position="fixed">SpO2 on air</ion-label>
<ion-input formControlName="spo2" type="number" pattern="[0-9]*" min="50" max="100" required></ion-input>
</ion-item>
<ion-item *ngIf="batsForm.get('spo2').dirty && errorControl.spo2.invalid">
<ion-text color="danger" *ngIf="batsForm.get('spo2').dirty && errorControl.spo2.errors?.min">
SpO2 be greater than 50%
</ion-text>
<ion-text color="danger" *ngIf="batsForm.get('spo2').dirty && errorControl.spo2.errors?.max">
SpO2 must be 100% or less
</ion-text>
<ion-text color="danger"*ngIf="batsForm.get('spo2').dirty && errorControl.spo2.errors?.required">
SpO2 is required when a respiratory rate is not provided
</ion-text>
</ion-item>
<ion-item>
<ion-label position="fixed">Heart Rate </ion-label>
<ion-input formControlName="hr" type="number" pattern="[0-9]*" min="0" max="180" id="hr" required></ion-input>
</ion-item>
<ion-item *ngIf="batsForm.get('hr').dirty && errorControl.hr.invalid">
<ion-text color="danger" *ngIf="batsForm.get('hr').dirty && errorControl.hr.errors?.min">
Heart rate must be greater than 0
</ion-text>
<ion-text color="danger" *ngIf="batsForm.get('hr').dirty && errorControl.hr.errors?.max">
Heart rate must be less than 180
</ion-text>
<ion-text color="danger"*ngIf="batsForm.get('hr').dirty && errorControl.hr.errors?.required">
Heart rate value is required
</ion-text>
</ion-item>
<ion-item>
<ion-label position="fixed">Callsign</ion-label>
<ion-input formControlName="callsign" type="number" pattern="[0-9]*" required placeholder="Enter vehicle callsign"></ion-input>
</ion-item>
<ion-item *ngIf="batsForm.get('callsign').dirty && errorControl.callsign.invalid">
<ion-text color="danger"*ngIf="batsForm.get('callsign').dirty && errorControl.callsign.errors?.required">
Your vehicle callsign is required
</ion-text>
</ion-item>
<div class="ion-padding">
<ion-button expand="full" type="submit" class="ion-no-margin" [disabled]="!batsForm.valid" >Calculate Score</ion-button>
</div>
</form>
</ion-content>
tab1.page.ts
import { LoadingController } from '@ionic/angular';
import { NetworkStatus } from '@capacitor/core';
import { Plugins } from '@capacitor/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { distinctUntilChanged } from 'rxjs/operators';
import { Router } from '@angular/router';
const { Network } = Plugins;
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page implements OnInit {
status: NetworkStatus;
batsForm: FormGroup;
thenumbers = new Array(100);
public show = true;
public spinner = false;
public loading = null;
public isSubmitted = false;
public startGCS = 15;
public nextID = 1;
public age: any;
public period: any;
constructor(
private loadingCtrl: LoadingController,
public formBuilder: FormBuilder,
private router: Router
) { }
ngOnInit() {
this.batsForm = this.formBuilder.group({
bp : ['', [Validators.required, Validators.min(0), Validators.max(240)]],
gcs : ['', [Validators.required, Validators.min(3), Validators.max(15)]],
rr : ['', [Validators.required, Validators.min(0), Validators.max(60)]],
spo2 : ['', [Validators.required, Validators.min(50), Validators.max(100)]],
hr : ['', [Validators.required, Validators.min(0), Validators.max(180)]],
age : ['', [Validators.required, Validators.min(0), Validators.max(115)]],
period : ['', [Validators.required]],
penetrating : ['', [Validators.required]],
velocity : ['', [Validators.required]],
callsign : ['', [Validators.required]]
});
this.batsForm.controls.period.setValue('years');
this.formControlValueChanged();
}
ionViewDidEnter() {
this.getStatus();
this.nextID = 1;
}
async getStatus() {
try {
this.status = await Network.getStatus();
console.log(this.status);
} catch (e) {
console.log('Error', e);
}
}
get errorControl() {
return this.batsForm.controls;
}
// tslint:disable-next-line: max-line-length
// https://www.infragistics.com/community/blogs/b/infragistics/posts/how-to-do-conditional-validation-on-valuechanges-method-in-angular-reactive-forms-
// https://stackoverflow.com/questions/47821809/rangeerror-maximum-call-stack-size-exceeded-when-using-valuechanges-subscribe
formControlValueChanged() {
const spo2Control = this.batsForm.get('spo2');
const rrControl = this.batsForm.get('rr');
this.batsForm.get('rr').valueChanges.pipe(distinctUntilChanged()).subscribe(
(rr: number) => {
console.log(rr);
if ( rr !== null && ( rr > 0 || rr < 50 )) {
spo2Control.setValidators([Validators.min(50), Validators.max(100)]);
} else {
spo2Control.setValidators([Validators.required, Validators.min(50), Validators.max(100)]);
}
spo2Control.updateValueAndValidity();
});
this.batsForm.get('spo2').valueChanges.pipe(distinctUntilChanged()).subscribe(
(spo2: number) => {
console.log(spo2);
if (spo2 !== null && ( spo2 > 50 || spo2 < 101 )) {
rrControl.setValidators([Validators.min(0), Validators.max(60)]);
} else {
rrControl.setValidators([Validators.required, Validators.min(0), Validators.max(60)]);
}
rrControl.updateValueAndValidity();
});
}
submitForm() {
console.log('Form submitted');
console.log(this.batsForm.value);
}
}