From 17ba38b26f943b518ed8c27ce7fd49125e107652 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Mon, 29 Jan 2018 10:30:12 +0100
Subject: [PATCH] =?UTF-8?q?remaniement=20GenericInputComponent=20:=20possi?=
 =?UTF-8?q?bilit=C3=A9=20que=20la=20valeur=20g=C3=A9r=C3=A9e=20ne=20soit?=
 =?UTF-8?q?=20plus=20seulement=20un=20type=20simple=20mais=20le=20membre?=
 =?UTF-8?q?=20d'une=20classe?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../generic-input/generic-input.component.ts  | 118 ++++++++++++++++--
 1 file changed, 105 insertions(+), 13 deletions(-)

diff --git a/src/app/components/generic-input/generic-input.component.ts b/src/app/components/generic-input/generic-input.component.ts
index 4458edfeb..e3359da12 100644
--- a/src/app/components/generic-input/generic-input.component.ts
+++ b/src/app/components/generic-input/generic-input.component.ts
@@ -15,10 +15,19 @@ exemple de template :
 /**
  * classe de gestion générique d'un champ de saisie avec titre, validation et message d'erreur
  * définitions :
- * - modèle : valeur gérée, indépendement de la façon dont elle est affichée
+ * - modèle : entité mémoire gérée, indépendamment de la façon dont elle est affichée.
+ *   A noter que si cette entité est une classe, on peut ne présenter à l'interface qu'un membre de cette classe,
+ *   cad que get model() et getModelValue() ne renverront pas la même chose.
+ *   Par ex : get model()-> instance_de_la_classe_Toto, getModelValue() -> Toto.unMembreNumerique
+ * - valeur gérée : entité elle même si c'est un type simple (number, string, ...) ou une partie d'un classe
  * - UI : interface utilisateur, présentation de la valeur gérée
  */
 export abstract class GenericInputComponent extends BaseComponent {
+    /**
+     * entité mémoire gérée
+     */
+    protected _model: any;
+
     /**
      * flag de désactivation de l'input
      */
@@ -131,7 +140,7 @@ export abstract class GenericInputComponent extends BaseComponent {
     }
 
     public get model(): any {
-        return this.getModelValue();
+        return this._model;
     }
 
     /**
@@ -149,8 +158,10 @@ export abstract class GenericInputComponent extends BaseComponent {
     }
 
     public set model(v: any) {
-        this.setAndValidateModel(v);
-        this.updateAndValidateUI();
+        this.beforeSetModel();
+        this._model = v;
+        this.afterSetModel();
+        this.updateAll();
     }
 
     /**
@@ -175,15 +186,29 @@ export abstract class GenericInputComponent extends BaseComponent {
             this.setAndValidateModel(this.uiToModel(ui));
     }
 
+    private updateAll() {
+        this.updateAndValidateUI();
+        this.validateModel();
+    }
+
     /**
      * appelé après le 1er affichage du composant
      * @see BaseComponent
      */
     protected afterFirstViewChecked() {
-        this.updateAndValidateUI();
-        this.validateModel();
+        this.updateAll();
     }
 
+    /**
+     * appelé avant le changement de modèle
+     */
+    protected beforeSetModel() { }
+
+    /**
+     * appelé après le changement de modèle
+     */
+    protected afterSetModel() { }
+
     /**
      * retourne la valeur du modèle
      */
@@ -196,7 +221,7 @@ export abstract class GenericInputComponent extends BaseComponent {
 
     /**
      * valide une valeur de modèle : est ce une valeur acceptable ? (par ex, nombre dans un intervalle, valeur dans une liste, ...)
-     * @param v valide la valeur du modèle
+     * @param v valeur à valider
      * @returns isValid : true si la valeur est valide, false sinon
      * @returns message : message d'erreur
      */
@@ -209,7 +234,7 @@ export abstract class GenericInputComponent extends BaseComponent {
 
     /**
      * valide une valeur saisie dans l'UI (forme de la saisie : est ce bien une date, un nombre, ...)
-     * @param ui valide la valeur saisie
+     * @param ui saisie à valider
      * @returns isValid : true si la valeur est valide, false sinon
      * @returns message : message d'erreur
      */
@@ -222,7 +247,7 @@ export abstract class GenericInputComponent extends BaseComponent {
 }
 
 /*
- * exemple d'utilisation de GenericInputComponent
+ * exemples d'utilisation de GenericInputComponent
  */
 
 /*
@@ -230,17 +255,17 @@ import { Component } from "@angular/core";
 
 import { NumericalString, Message } from "jalhyd";
 
+// exemple où le modèle est un type simple (number)
+
 @Component({
     selector: "test-input",
     template: `<div class="md-form form-sm">
-    <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [ngModel]="uiValue" (ngModelChange)="setUIValue($event)">
+    <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue">
     <label for="form1">{{_title}}</label>
-    <small class="text-danger">{{_message}}</small>
+    <small *ngIf="showError" class="text-danger">{{errorMessage}}</small>
 </div>`
 })
 export class TestInputComponent extends GenericInputComponent {
-    private _model: number;
-
     constructor() {
         super();
         this._model = 0;
@@ -289,4 +314,71 @@ export class TestInputComponent extends GenericInputComponent {
         return +ui;
     }
 }
+
+
+// exemple où le modèle est une classe dont on ne gère qu'un membre
+
+import { BaseParam } from "jalhyd";
+
+@Component({
+    selector: "test2-input",
+    template: `<div class="md-form form-sm">
+    <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue">
+    <label for="form1">{{_title}}</label>
+    <small *ngIf="showError" class="text-danger">{{errorMessage}}</small>
+</div>`
+})
+export class Test2InputComponent extends GenericInputComponent {
+    constructor() {
+        super();
+    }
+
+    // paramètre géré
+    private get _param(): BaseParam {
+        return this._model;
+    }
+
+    protected getModelValue(): any {
+        return this._param.getValue();
+    }
+
+    protected setModelValue(v: any) {
+        this._param.setValue(v);
+    }
+
+    protected validateModelValue(v: any): { isValid: boolean, message: string } {
+        let msg = undefined;
+        let valid = false;
+
+        if (v < 0)
+            msg = "La valeur n'est pas >= 0 ";
+        else
+            valid = true;
+
+        return { isValid: valid, message: msg };
+    }
+
+    protected modelToUI(v: any): string {
+        if (typeof (v) == "number")
+            return String(v);
+        return undefined;
+    }
+
+    protected validateUIValue(ui: string): { isValid: boolean, message: string } {
+        let valid: boolean = false;
+        let msg: string = undefined;
+
+        let v: NumericalString = new NumericalString(ui);
+        if (!v.isNumerical)
+            msg = "Veuillez entrer une valeur numérique";
+        else
+            valid = true;
+
+        return { isValid: valid, message: msg };
+    }
+
+    protected uiToModel(ui: string): any {
+        return +ui;
+    }
+}
 /**/
-- 
GitLab