From 5d9529c9557f296c458ee6a3c60e4fff4fdfc23a Mon Sep 17 00:00:00 2001 From: "francois.grand" <francois.grand@irstea.fr> Date: Thu, 13 Jul 2017 11:01:25 +0200 Subject: [PATCH] =?UTF-8?q?correction=20de=20bugs=20quand=202=20contr?= =?UTF-8?q?=C3=B4les=20de=20saisie=20de=20param=C3=A8tre=20g=C3=A8re=20le?= =?UTF-8?q?=20m=C3=AAme=20param=C3=A8tre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.component.ts | 1 + .../param-input/param-input.component.html | 13 +- src/app/param-input/param-input.component.ts | 162 ++++++++++++++---- src/app/param-service/param.service.ts | 4 +- 4 files changed, 138 insertions(+), 42 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8a85a6876..8e8a97224 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -7,6 +7,7 @@ import { ParamService } from './param-service/param.service'; template: ` <h1>{{title}}</h1> <param-input symbol="Q"></param-input> + <param-input symbol="Q"></param-input> <param-input symbol="Ks"></param-input> <!-- --> diff --git a/src/app/param-input/param-input.component.html b/src/app/param-input/param-input.component.html index 7aa49591b..265cb5a83 100644 --- a/src/app/param-input/param-input.component.html +++ b/src/app/param-input/param-input.component.html @@ -1,4 +1,13 @@ <md-input-container> - <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="_paramDef.v" (ngModelChange)="setValue($event)" /> + <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="_uiValue.uncheckValueString" (ngModelChange)="setValue($event)" + /> <md-hint>{{_message}}</md-hint> -</md-input-container> \ No newline at end of file +</md-input-container> +<!-- + <md-error *ngIf="_message"> + {{_message}} + </md-error> + <input mdInput placeholder="{{_paramDef.symbol}}" [ngModel]="getValue()" (ngModelChange)="setValue($event)" /> + <md-error *ngIf="hasError()"> + <md-hint *ngIf="hasError()">{{_message}}</md-hint> +--> \ No newline at end of file diff --git a/src/app/param-input/param-input.component.ts b/src/app/param-input/param-input.component.ts index ef7041a29..ead9e0285 100644 --- a/src/app/param-input/param-input.component.ts +++ b/src/app/param-input/param-input.component.ts @@ -1,9 +1,9 @@ // cf. https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html -import { Component, Input, forwardRef, OnInit, OnChanges } from '@angular/core'; +import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from '@angular/forms'; -import { ParamDefinition } from 'jalhyd'; +import { ParamDefinition, NumericalString } from 'jalhyd'; import { ParamService } from '../param-service/param.service'; @@ -27,7 +27,7 @@ import { ParamService } from '../param-service/param.service'; } ] }) -export class ParamInputComponent implements ControlValueAccessor, OnInit { +export class ParamInputComponent implements ControlValueAccessor, OnInit, DoCheck { /** * Parameter symbol (Q, Ks, B, ...) attribute */ @@ -41,67 +41,144 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit { private _message: string; - constructor(private paramService: ParamService) { + private static _idGen: number = 0; // A VIRER + private _id: number; // A VIRER + private static _startTime: number; // A VIRER + + /** + * true si la modification du paramètre géré vient de l'interface utilisateur + * + * false si la modification du paramètre géré vient d'un appel du code + */ + private _fromUI: boolean; + + /** + * valeur dans le contrôle (saisie par l'utilisateur) + */ + // private _uiValue: string; + private _uiValue: NumericalString; + + constructor(private paramService: ParamService, private changeDetector: ChangeDetectorRef) { + this._id = ParamInputComponent._idGen++; + if (ParamInputComponent._startTime == undefined) + ParamInputComponent._startTime = new Date().getTime(); + + this._uiValue = new NumericalString(); } - private setValue(event: any) { - this.log("ParamInputComponent.setValue"); - this.log(event); - this.validateValue(event); + hasError(): boolean { + let res = (this._message != undefined); + if (res) + this.log("hasError : true " + this._message); + else + this.log("hasError : false"); + return res; } - ngOnInit() { - this.log("ParamInputComponent.ngOnInit"); + private getSfromUI(): string { + return this._fromUI ? " fromUI " : " fromMODEL"; + } + + private getSParam(): string { + return " " + this._paramDef.symbol + "=" + this._paramDef.toString() + } + private getSUIvalue(v: NumericalString = undefined): string { + if (v == undefined) + return " uiValue=" + this._uiValue.toString() + ""; + + return " uiValue=" + v.toString() + ""; + } + + ngOnInit() { // retrieve parameter from symbol this._paramDef = this.paramService.getParameter(this._paramSymbol); } - private validateValue(val: any) { - this.log(""); + // private getValue() { + // if (this._paramDef.isDefined) + // return this._paramDef.v; + // return ""; - let sVal: string; + // // return this._uiValue.value; + // } - let isNum = true; - if (val == undefined) { - sVal = "undefined"; - isNum = false; - } + /** + * fonction appelée lorsque l'utilisateur fait une saisie + * @param event valeur du contrôle + */ + private setValue(event: any) { + this._fromUI = true; + this._uiValue.value = event; + this.log(this._uiValue.toString()); + return this.validateUIValue(); + } + + /** + * fonction appelée lors d'un rafraîchissement de l'UI + */ + ngDoCheck(): void { + this.log("ngDoCheck start : " + this.getSParam() + this.getSUIvalue() + this.getSfromUI()); + + if (this._fromUI) + this.updateMessage(this._uiValue); else { - if (typeof val === "string") { - isNum = String(val).trim() !== "" && !isNaN(+val) - sVal = String(val); + if (this._paramDef.isDefined) { + this.updateMessage(new NumericalString(this._paramDef.v)); + this._uiValue.value = String(this._paramDef.v); } + else + this.updateMessage(this._uiValue); } - this.log("ParamInputComponent.validateValue -" + sVal + "-"); - let ok: boolean = true; - this._message = undefined; - if (!isNum) { - ok = false; - this._message = "Please enter a numerical value"; - } + this.log("ngDoCheck end : " + this.getSParam() + this.getSUIvalue()); - if (ok) { - let nVal = +val; + this._fromUI = false; + } + + private updateMessage(v: NumericalString) { + this.log("updateMessage start :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + " message=" + this._message); + + if (v.isNumerical) { + this._message = undefined; try { - this._paramDef.v = nVal; + this._paramDef.checkValue(v.numericalValue); } catch (e) { this._message = e; - ok = false; } } + else + this._message = "Please enter a numerical value"; + + this.log("updateMessage end :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + " message=" + this._message); + } + private validateUIValue() { + this.log(""); + this.log("validateValue start : val '" + this._uiValue.toString() + "'" + this.getSParam() + this.getSfromUI()); + + let ok: boolean = this._uiValue.isNumerical; + if (ok) { + try { + if (!this._paramDef.isDefined || this._paramDef.v != this._uiValue.numericalValue) { + this._paramDef.v = this._uiValue.numericalValue; + this.changeDetector.detectChanges(); // provoque une détection des changements dans les contrôles + } + } + catch (e) { + ok = false; + } + } if (!ok) { - //this._paramDef.undefine(); - this.log("ParamInputComponent.param " + this._paramDef.toString()); + this.log("validateValue end : " + this.getSParam()); let err = { rangeError: { - given: val, + // given: val, + given: this._uiValue.toString(), max: 4, min: 0 } @@ -109,20 +186,29 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit { return err; } - this.log("ParamInputComponent.param " + this._paramDef.toString()); + this.log("validateValue end : " + this.getSParam()); return null; } private log(m: string) { - // console.log(m); + let t: number = new Date().getTime() - ParamInputComponent._startTime; + console.log("ParamInputComponent(" + this._id + ") " + t + " : " + m); } // ControlValueAccessor interface propagateChange = (_: any) => { }; + /* + //From ControlValueAccessor interface + writeValue(value: any) { + if (value !== this.innerValue) { + this.innerValue = value; + } + } + */ writeValue(value: any) { - this.log("ParamInputComponent.writeValue " + value); + this.log("writeValue " + value); } registerOnChange(fn: any) { diff --git a/src/app/param-service/param.service.ts b/src/app/param-service/param.service.ts index fa5e49fcf..7b6654fea 100644 --- a/src/app/param-service/param.service.ts +++ b/src/app/param-service/param.service.ts @@ -4,8 +4,8 @@ export class ParamService { private _params: ParamDefinition[]; constructor() { - this._params = [new ParamDefinition('Q', ParamDomainValue.POS_NULL, 0), - new ParamDefinition('Ks', ParamDomainValue.POS, 1)]; + this._params = [new ParamDefinition('Q', ParamDomainValue.POS_NULL), + new ParamDefinition('Ks', ParamDomainValue.POS)]; for (let p of this._params) p.calculability = ParamCalculability.DICHO; } -- GitLab