diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 3fed50b3544cc601da93f2806db091eb84c968cd..6938cf1688d2fcdd52793b38c9bd32a18a0c4555 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -5,15 +5,13 @@ import { Router } from '@angular/router';
 
 import { ComputeNodeType, ComputeNode } from 'jalhyd';
 
-import { ParamService } from './services/param/param.service';
-import { HttpService } from './services/http/http.service';
 import { InternationalisationService, Language, LanguageCode } from './services/internationalisation/internationalisation.service';
 import { Observer } from './services/observer';
 import { ErrorService } from './services/error/error.service';
 // import { AlertDialog } from './components/alert-dialog/alert-dialog.component';
 import { FormulaireService } from './services/formulaire/formulaire.service';
-import { FormulaireElement } from './formulaire/formulaire-element';
 import { FormulaireDefinition, CalculatorType } from './formulaire/formulaire-definition';
+import { OnInit, OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks';
 
 
 @Component({
@@ -21,7 +19,7 @@ import { FormulaireDefinition, CalculatorType } from './formulaire/formulaire-de
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.scss']
 })
-export class AppComponent implements Observer {
+export class AppComponent implements OnInit, OnDestroy, Observer {
   private _currentLanguage: LanguageCode;
 
   private _displayErrorDialog: boolean = false;
@@ -35,7 +33,6 @@ export class AppComponent implements Observer {
     private router: Router,
     private formulaireService: FormulaireService
   ) {
-    this.formulaireService.addObserver(this);
   }
 
   private initLocale() {
@@ -52,9 +49,15 @@ export class AppComponent implements Observer {
 
   ngOnInit() {
     this.initLocale();
+    this.formulaireService.addObserver(this);
     this.subscribeErrorService();
   }
 
+  ngOnDestroy() {
+    this.unsubscribeErrorService();
+    this.formulaireService.removeObserver(this);
+  }
+
   private _displayedCalc: ComputeNodeType;
 
   /**
@@ -64,6 +67,10 @@ export class AppComponent implements Observer {
     this.errorService.addObserver(this);
   }
 
+  private unsubscribeErrorService() {
+    this.errorService.removeObserver(this);
+  }
+
   private selectLang(lc: LanguageCode) {
     this.intlService.setLocale(lc);
 
diff --git a/src/app/calculators/generic/calculator.component.html b/src/app/calculators/generic/calculator.component.html
index a513d02350f2aeed50ac91f87dc063dd63e5469d..c04760e666baf1f3527fab84f66cfe1881c9d887 100644
--- a/src/app/calculators/generic/calculator.component.html
+++ b/src/app/calculators/generic/calculator.component.html
@@ -3,8 +3,8 @@
         <h1>{{uitextTitre}}</h1>
     </div>
 </div>
-<field-set *ngFor="let fs of fieldSets" [style.display]="getFieldsetStyleDisplay(fs.id)" [formId]=_formulaire.uid [id]=fs.id
-    [fieldSet]=fs (onRadio)=onRadioClick($event) (onSelectChange)=onSelectChanged($event)></field-set>
+<field-set *ngFor="let fs of fieldSets" [style.display]="getFieldsetStyleDisplay(fs.id)" [fieldSet]=fs (onRadio)=onRadioClick($event)
+    (onSelectChange)=onSelectChanged($event)></field-set>
 
 <div class="row ">
     <div class="col text-center">
diff --git a/src/app/calculators/generic/calculator.component.ts b/src/app/calculators/generic/calculator.component.ts
index df4d9da122988b2b7b749b5db20982c4c57850ef..228c1fe5a25593da9a08410eb96690fa2dc0a64c 100644
--- a/src/app/calculators/generic/calculator.component.ts
+++ b/src/app/calculators/generic/calculator.component.ts
@@ -1,21 +1,11 @@
-import { Component, Inject, OnInit, DoCheck, ViewChild, Input } from "@angular/core";
-import { ActivatedRoute, ParamMap } from '@angular/router';
+import { Component, OnInit, DoCheck, OnDestroy, ViewChild } from "@angular/core";
+import { ActivatedRoute } from '@angular/router';
 
-import { ComputeNodeType } from "jalhyd";
-
-import { ParamService } from "../../services/param/param.service";
-import { HttpService } from "../../services/http/http.service";
 import { FormulaireService } from "../../services/formulaire/formulaire.service";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { FieldSet } from "../../formulaire/fieldset";
-import { InputField } from "../../formulaire/input-field";
-import { SelectField } from "../../formulaire/select-field";
 import { FormulaireDefinition } from "../../formulaire/formulaire-definition";
 import { CalculatorType } from "../../formulaire/formulaire-definition";
-import { Dependency } from "../../formulaire/dependency";
-import { ExistenceDependency } from "../../formulaire/existence-dependency";
-import { ValueDependency } from "../../formulaire/value-dependency";
-import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam";
 import { CalculatorResultsComponent } from "../../components/calculator-results/calculator-results.component";
 import { Observer } from "../../services/observer";
 import { Subscription } from "rxjs/Subscription";
@@ -32,7 +22,7 @@ import { Subscription } from "rxjs/Subscription";
     `
     ]
 })
-export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
+export class GenericCalculatorComponent implements OnInit, DoCheck, OnDestroy, Observer {
     /**
      * composant d'affichage des résultats
      */
@@ -44,13 +34,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
      */
     private _formulaire: FormulaireDefinition;
 
-    constructor(private paramService: ParamService,
-        private httpService: HttpService,
-        private intlService: InternationalisationService,
+    private _subscription: Subscription; // pour souscrire aux changements d'URL envoyés par le routeur
+
+    constructor(private intlService: InternationalisationService,
         private formulaireService: FormulaireService,
         private route: ActivatedRoute) {
-        this.intlService.addObserver(this);
-        this.formulaireService.addObserver(this);
     }
 
     private get fieldSets(): FieldSet[] {
@@ -85,17 +73,10 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
         return this.intlService.localizeText("INFO_CALCULATOR_CALCULER");
     }
 
-    private _subscription: Subscription;
-
     ngOnInit() {
-        // récupération des paramètres passés avec la route (URL)
-        this._subscription = this.route.params.subscribe(params => {
-            const uid: number = +params['uid'];
-
-            this._formulaire = this.formulaireService.getFormulaireFromId(uid);
-            this.resultsComponent.formulaire = this._formulaire;
-            this._formulaire.updateNodeType();
-        });
+        this.intlService.addObserver(this);
+        this.formulaireService.addObserver(this);
+        this.subscribeRouter();
     }
 
     ngDoCheck() {
@@ -109,6 +90,23 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
     }
 
     ngOnDestroy() {
+        this.unsubscribeRouter();
+        this.formulaireService.removeObserver(this);
+        this.intlService.removeObserver(this);
+    }
+
+    private subscribeRouter() {
+        // récupération des paramètres passés avec la route (URL)
+        this._subscription = this.route.params.subscribe(params => {
+            const uid: number = +params['uid'];
+
+            this._formulaire = this.formulaireService.getFormulaireFromId(uid);
+            this.resultsComponent.formulaire = this._formulaire;
+            this._formulaire.updateNodeType();
+        });
+    }
+
+    private unsubscribeRouter() {
         this._subscription.unsubscribe();
     }
 
@@ -123,11 +121,16 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, Observer {
         let option: string = tmp[1]; // nouvel état (radio)
 
         this._formulaire.resetRadiosAndResults(symbol, option);
-
-        // this.appRef.tick();
-        //        this.changeDetectorRef.detectChanges();  // provoque une détection des changements dans les contrôles
     }
 
+    /**
+     * met à jour l'interface
+     */
+    //    private updateUI() {
+    // this.appRef.tick();
+    // this.changeDetectorRef.detectChanges();  // provoque une détection des changements dans les contrôles
+    //}
+
     private doCompute() {
         this._formulaire.doCompute();
         this.resultsComponent.updateView();
diff --git a/src/app/components/calculator-list/calculator-list.component.ts b/src/app/components/calculator-list/calculator-list.component.ts
index d2db5a80b37a7e67982b4a9ea38c12c216cfecf1..e7b41b35f243ab373e3418482051d5c46cf70d7e 100644
--- a/src/app/components/calculator-list/calculator-list.component.ts
+++ b/src/app/components/calculator-list/calculator-list.component.ts
@@ -28,7 +28,6 @@ export class CalculatorListComponent {
     }
 
     private create(t: CalculatorType) {
-        console.log("create", t);
         const p: Promise<FormulaireDefinition> = this.formulaireService.createFormulaire(t);
         p.then(f => {
             this.router.navigate(['/calculator', f.uid]);
diff --git a/src/app/components/check-field-line/check-field-line.component.ts b/src/app/components/check-field-line/check-field-line.component.ts
index 877a4e92d5cb871f72df938bcfeb5e9a16da4f10..6897543d23e5415f951fa89838301e0638953b29 100644
--- a/src/app/components/check-field-line/check-field-line.component.ts
+++ b/src/app/components/check-field-line/check-field-line.component.ts
@@ -8,6 +8,7 @@ import { FormulaireService } from "../../services/formulaire/formulaire.service"
     templateUrl: "./check-field-line.component.html",
 })
 export class CheckFieldLineComponent {
+    @Input("param")
     private _check: CheckField;
 
     private _currentValue: boolean;
@@ -15,39 +16,6 @@ export class CheckFieldLineComponent {
     constructor(private formulaireService: FormulaireService) {
     }
 
-    private updateField() {
-        if (this._formId == undefined || this._id == undefined)
-            this._check = undefined;
-        else
-            this._check = this.formulaireService.getCheckField(this._formId, this._id);
-    }
-
-    /**
-    * id input attribute
-    */
-    private _id: string;
-
-    @Input()
-    private set id(s: string) {
-        this._id = s;
-        this.updateField();
-    }
-
-    /**
-    * form id input attribute
-    */
-    private _formId: number;
-
-    private get formId(): number {
-        return this._formId;
-    }
-
-    @Input()
-    private set formId(id: number) {
-        this._formId = id;
-        this.updateField();
-    }
-
     private onChange(event: any) {
         this._check.setValue(event);
     }
diff --git a/src/app/components/field-set/field-set.component.html b/src/app/components/field-set/field-set.component.html
index 2d171bfbd8751cd8619a26d543e16dbfefac00bb..9539cd8f0b121a026d4fea761b36bb0af49ff754 100644
--- a/src/app/components/field-set/field-set.component.html
+++ b/src/app/components/field-set/field-set.component.html
@@ -14,12 +14,12 @@
     </ng-template>
 -->
 
-<ng-template ngFor let-p [ngForOf]="_fieldSet.fields">
-    <param-field-line *ngIf="p.isInput" [formId]=formId [computeNodeType]=_fieldSet.computeNodeType [symbol]=p.symbol (onRadio)=onRadioClick($event)>
+<ng-template ngFor let-p [ngForOf]="fields">
+    <param-field-line *ngIf="p.isInput" [param]=p (onRadio)=onRadioClick($event)>
     </param-field-line>
 
-    <select-field-line *ngIf="p.isSelect" [formId]=formId [id]=p.id (onSelectChange)=onSelectChanged($event)>
+    <select-field-line *ngIf="p.isSelect" [param]=p (onSelectChange)=onSelectChanged($event)>
     </select-field-line>
 
-    <check-field-line *ngIf="p.isCheck" [formId]=formId [id]=p.id></check-field-line>
+    <check-field-line *ngIf="p.isCheck" [param]=p></check-field-line>
 </ng-template>
\ No newline at end of file
diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index e89d6bd4d439f1b3e722d59ae4f9b7ea8c682272..817875d6e58a34aff9b80f81febe1cac327168a4 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -30,21 +30,8 @@ export class FieldSetComponent {
         this._fieldSet = fs;
     }
 
-    /**
-    * form id input attribute
-    */
-    private _formId: number;
-
-    private get formId(): number {
-        return this._formId;
-    }
-
-    @Input()
-    private set formId(id: number) {
-        this._formId = id;
-    }
-
-    constructor() {
+    private get fields() {
+        return this._fieldSet.fields;
     }
 
     private hasRadioFix(): boolean {
@@ -110,7 +97,6 @@ export class FieldSetComponent {
      * réception d'un événement d'un select
      */
     private onSelectChanged(val: string) {
-        //console.log("fieldset " + val);
         this.onSelectChange.emit(val); // on transmet au parent
     }
 
diff --git a/src/app/components/param-field-line/param-field-line.component.html b/src/app/components/param-field-line/param-field-line.component.html
index a00eb1d1fd82f7e3136b03339a99e85d1c53fe4b..a623902d3fcae3cee5cb8e0782ffdca74e4c9904 100644
--- a/src/app/components/param-field-line/param-field-line.component.html
+++ b/src/app/components/param-field-line/param-field-line.component.html
@@ -6,7 +6,7 @@
 
     <!-- input de saisie de la valeur -->
     <div class="col-sm-2">
-        <param-input [inputDisabled]="isInputDisabled" [computeNodeType]="nodeType" [symbol]="symbol"></param-input>
+        <param-input [inputDisabled]="isInputDisabled" [param]="_param"></param-input>
     </div>
 
     <!-- radio "fixé" -->
@@ -58,4 +58,4 @@
             <input type="text" class="input-alternate" name="inputstep" placeholder="step" [(ngModel)]="_param.stepValue" />
         </div>
     </div>
-</div>
+</div>
\ No newline at end of file
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 8781c20f40d572c24849ba2f249f453a6442cfb8..7322e66decea65d532a48d9dac2a2cef0a13bcaf 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -2,7 +2,6 @@ import { Component, Input, Output, DoCheck, EventEmitter } from "@angular/core";
 
 import { ComputeNodeType } from "jalhyd";
 
-import { ParamService } from "../../services/param/param.service";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam";
 
@@ -11,9 +10,10 @@ import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam";
     templateUrl: "./param-field-line.component.html"
 })
 export class ParamFieldLineComponent {
+    @Input("param")
     private _param: NgParameter;
 
-    constructor(private paramService: ParamService, private intlService: InternationalisationService) {
+    constructor(private intlService: InternationalisationService) {
     }
 
     private get title(): string {
@@ -49,20 +49,6 @@ export class ParamFieldLineComponent {
         return this.intlService.localizeText("INFO_PARAMFIELD_PARAMCALCULER");
     }
 
-    /**
-     * type de noeud de calcul
-     */
-    private _computeNode: ComputeNodeType;
-
-    private get nodeType(): ComputeNodeType {
-        return this._computeNode;
-    }
-
-    @Input()
-    private set computeNodeType(t: ComputeNodeType) {
-        this._computeNode = t;
-    }
-
     /**
      * Parameter symbol (Q, Ks, B, ...) input attribute
      */
@@ -70,28 +56,6 @@ export class ParamFieldLineComponent {
         return this._param.symbol;
     }
 
-    @Input()
-    private set symbol(s: string) {
-        this._param = this.paramService.getParameter(this._computeNode, s);
-        if (this._param == undefined)
-            throw "symbole de paramètre '" + s + "' incorrect";
-    }
-
-    /**
-    * form id input attribute
-    */
-    private _formId: number;
-
-    private get formId(): number {
-        return this._formId;
-    }
-
-    @Input()
-    private set formId(id: number) {
-        this._formId = id;
-        // this.updateField();
-    }
-
     /**
      * calcule la présence du radio "paramètre fixé"
      */
diff --git a/src/app/components/param-input/param-input.component.ts b/src/app/components/param-input/param-input.component.ts
index 930aa16a9d653190ee0ee8e84773d11d1b189195..8d867a8db26727db4602c8bc5fc9b8b6671bced8 100644
--- a/src/app/components/param-input/param-input.component.ts
+++ b/src/app/components/param-input/param-input.component.ts
@@ -5,16 +5,11 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } f
 
 import { ComputeNodeType, ParamDefinition, NumericalString, Message, MessageCode } from "jalhyd";
 
-import { ParamService } from "../../services/param/param.service";
 import { InternationalisationService, LanguageCode } from "../../services/internationalisation/internationalisation.service";
 import { NgParameter } from "../../formulaire/ngparam";
 
 @Component({
     selector: "param-input",
-    /* OK
-    <input placeholder="{{_paramDef.symbol}}" [ngModel]="_paramDef.v" (ngModelChange)="setValue($event)"/>
-    <p *ngIf="_message">{{_message}}</p>
-    */
     templateUrl: "./param-input.component.html",
     providers: [
         {
@@ -29,23 +24,7 @@ import { NgParameter } from "../../formulaire/ngparam";
         }
     ]
 })
-export class ParamInputComponent implements ControlValueAccessor, OnInit, DoCheck {
-    /**
-     * type de noeud de calcul
-     */
-    private _computeNode: ComputeNodeType;
-
-    @Input()
-    private set computeNodeType(t: ComputeNodeType) {
-        this._computeNode = t;
-    }
-
-    /**
-     * Parameter symbol (Q, Ks, B, ...) attribute
-     */
-    @Input('symbol')
-    private _paramSymbol: string;
-
+export class ParamInputComponent implements ControlValueAccessor, DoCheck {
     /**
      * enable/disable input field
      */
@@ -55,6 +34,7 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
     /**
      * managed parameter
      */
+    @Input('param')
     private _paramDef: NgParameter;
 
     private _message: string;
@@ -66,7 +46,6 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
 
     /**
      * 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;
@@ -76,17 +55,12 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
      */
     private _uiValue: NumericalString;
 
-    constructor(private paramService: ParamService, private changeDetector: ChangeDetectorRef, private intlService: InternationalisationService) {
+    constructor(private changeDetector: ChangeDetectorRef, private intlService: InternationalisationService) {
         this._uiValue = new NumericalString();
     }
 
     hasError(): boolean {
-        let res = (this._message != undefined);
-        // if (res)
-        //     this.log("hasError : true " + this._message);
-        // else
-        //     this.log("hasError : false");
-        return res;
+        return this._message != undefined;
     }
 
     private getSfromUI(): string {
@@ -108,11 +82,6 @@ export class ParamInputComponent implements ControlValueAccessor, OnInit, DoChec
         return this.intlService.localizeText("INFO_SAISIEPARAM_TITRE");
     }
 
-    ngOnInit() {
-        // retrieve parameter from symbol
-        this._paramDef = this.paramService.getParameter(this._computeNode, this._paramSymbol);
-    }
-
     /**
      * fonction appelée lorsque l'utilisateur fait une saisie
      * @param event valeur du contrôle
diff --git a/src/app/components/select-field-line/select-field-line.component.ts b/src/app/components/select-field-line/select-field-line.component.ts
index 4bce47b3bf48de653cfd68497b7ca37cda434b5a..fa3e248b04dc6f23da45dcdc553d74afa25bf6be 100644
--- a/src/app/components/select-field-line/select-field-line.component.ts
+++ b/src/app/components/select-field-line/select-field-line.component.ts
@@ -9,6 +9,7 @@ import { FormulaireService } from "../../services/formulaire/formulaire.service"
     templateUrl: "./select-field-line.component.html"
 })
 export class SelectFieldLineComponent {
+    @Input("param")
     private _select: SelectField;
 
     constructor(private formulaireService: FormulaireService) {
@@ -24,39 +25,6 @@ export class SelectFieldLineComponent {
         return "<no selection>";
     }
 
-    private updateField() {
-        if (this._formId == undefined || this._id == undefined)
-            this._select = undefined;
-        else
-            this._select = this.formulaireService.getSelectField(this._formId, this._id);
-    }
-
-    /**
-    * id input attribute
-    */
-    private _id: string;
-
-    @Input()
-    private set id(s: string) {
-        this._id = s;
-        this.updateField();
-    }
-
-    /**
-    * form id input attribute
-    */
-    private _formId: number;
-
-    private get formId(): number {
-        return this._formId;
-    }
-
-    @Input()
-    private set formId(id: number) {
-        this._formId = id;
-        this.updateField();
-    }
-
     /**
      * selected value event
      */
diff --git a/src/app/formulaire/check-field.ts b/src/app/formulaire/check-field.ts
index 645f27425e9e2dd1e52d92b16848f374542e02a3..56c317e8a79f8d45eb142c70369c6f4447868a03 100644
--- a/src/app/formulaire/check-field.ts
+++ b/src/app/formulaire/check-field.ts
@@ -7,8 +7,8 @@ import { DependencyConditionType } from "./dependency-condition";
 export class CheckField extends Field {
     private _value: boolean;
 
-    constructor(nodeType: ComputeNodeType, id: string) {
-        super(nodeType, id, FieldType.Check);
+    constructor(nodeType: ComputeNodeType, id: string, formId: number) {
+        super(nodeType, id, FieldType.Check, formId);
         this._value = false;
     }
 
diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts
index 7c8d8e5be3fd3cf90448920c1743315b78d8d972..401ca359cfa3cedb5e081e3684b84c2210fee78d 100644
--- a/src/app/formulaire/field.ts
+++ b/src/app/formulaire/field.ts
@@ -7,8 +7,8 @@ export enum FieldType {
 }
 
 export abstract class Field extends FormulaireElement {
-    constructor(nodeType: ComputeNodeType, id: string, private _fieldType: FieldType) {
-        super(nodeType, id);
+    constructor(nodeType: ComputeNodeType, id: string, private _fieldType: FieldType, formId: number) {
+        super(nodeType, id, formId);
     }
 
     public get isInput(): boolean {
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 4da0abba70dd8683c1fd727dd661dc465a828144..bb03abbcf6a96aa50e572637b27e0cbe5c83322a 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -10,8 +10,8 @@ import { NgParameter } from "./ngparam";
 export class FieldSet extends FormulaireElement {
     private _fields: Field[];
 
-    constructor(nodeType: ComputeNodeType, id: string) {
-        super(nodeType, id);
+    constructor(nodeType: ComputeNodeType, id: string, formId: number) {
+        super(nodeType, id, formId);
         this._fields = [];
     }
 
diff --git a/src/app/formulaire/formulaire-definition.ts b/src/app/formulaire/formulaire-definition.ts
index 94154fb25d13067a8d8d3c840f7cfd5b954ac43e..82771cde8dd5a788e7a4823fd796cc74587af03e 100644
--- a/src/app/formulaire/formulaire-definition.ts
+++ b/src/app/formulaire/formulaire-definition.ts
@@ -165,7 +165,6 @@ export class FormulaireDefinition {
         return undefined;
     }
 
-
     private removePrefix(s: string, prefix: string): string {
         if (s.startsWith(prefix)) {
             let l = prefix.length;
@@ -466,7 +465,7 @@ export class FormulaireDefinition {
 
     private parse_check(node_type: ComputeNodeType, field: {}): CheckField {
         let id = field["id"];
-        let res: CheckField = new CheckField(node_type, id);
+        let res: CheckField = new CheckField(node_type, id, this._uid);
         let value = field["value"];
 
         res.setValue(value == "true");
@@ -478,7 +477,7 @@ export class FormulaireDefinition {
 
     private parse_select(node_type: ComputeNodeType, field: {}): SelectField {
         let id = field["id"];
-        let res: SelectField = new SelectField(node_type, id);
+        let res: SelectField = new SelectField(node_type, id, this._uid);
         let values = field["select"];
 
         for (let v of values) {
@@ -493,7 +492,7 @@ export class FormulaireDefinition {
 
     private parse_input(node_type: ComputeNodeType, fieldset: {}, field: {}): NgParameter {
         let input_id: string = field["id"];
-        let res: NgParameter = this.paramService.getParameter(node_type, input_id);
+        let res: NgParameter = this.paramService.createParameter(node_type, input_id, this._uid);
         if (res == undefined)
             throw "pas de paramètre '" + input_id + "' trouvé dans le noeud " + ComputeNodeType[node_type] + "(" + node_type + ") ou " + ComputeNodeType[this._defaultNodeType] + "(" + this._defaultNodeType + ")";
 
@@ -515,7 +514,7 @@ export class FormulaireDefinition {
         let node_type: ComputeNodeType;
         node_type = nt == undefined ? this._defaultNodeType : ComputeNodeType[nt];
 
-        let res: FieldSet = new FieldSet(node_type, conf_id);
+        let res: FieldSet = new FieldSet(node_type, conf_id, this._uid);
         this._fieldSets.push(res);
 
         let fields = fieldset["fields"];
@@ -547,7 +546,7 @@ export class FormulaireDefinition {
         return undefined;
     }
 
-    private parseNodeType() {
+    private parseDefaultNodeType() {
         let nt: string = this.getOption("nodeType");
         if (nt == undefined)
             throw "l'option obligatoire 'nodeType' est absente du fichier de définition de formulaire";
@@ -559,7 +558,7 @@ export class FormulaireDefinition {
         this._dependencies = [];
         this._defaultCalculatedParam = undefined;
 
-        this.parseNodeType();
+        this.parseDefaultNodeType();
 
         for (let conf_index in this._config) {
             let conf = this._config[conf_index];
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index 82104104b65c4019c67e86dff31eddb8c30d07cf..69df8ebbb221b0f8c80367ffd2295111348a0fd0 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -8,13 +8,15 @@ import { StringMap } from "../stringmap";
 export abstract class FormulaireElement {
     private _nodeType: ComputeNodeType;
     private _id: string;
+    private _formId: number;
     public isDisplayed: boolean;
     public label: string;
 
-    constructor(nodeType: ComputeNodeType, id: string) {
+    constructor(nodeType: ComputeNodeType, id: string, formId: number) {
         this._nodeType = nodeType;
         this._id = id;
         this.isDisplayed = true;
+        this._formId = formId;
     }
 
     get computeNodeType(): ComputeNodeType {
@@ -25,6 +27,10 @@ export abstract class FormulaireElement {
         return this._id;
     }
 
+    get formId(): number {
+        return this._formId;
+    }
+
     protected abstract verifyDependency(d: Dependency): boolean;
 
     public verifiesDependency(d: Dependency): boolean {
diff --git a/src/app/formulaire/input-field.ts b/src/app/formulaire/input-field.ts
index 828cad3e4813bfcfb56752af241cc6e049d3022b..414e2e6ea92619fee6b656598bab450019ae1e7e 100644
--- a/src/app/formulaire/input-field.ts
+++ b/src/app/formulaire/input-field.ts
@@ -6,8 +6,8 @@ import { Field, FieldType } from "./field"
 export abstract class InputField extends Field {
     private _value: any;
 
-    constructor(type: ComputeNodeType, id: string) {
-        super(type, id, FieldType.Input);
+    constructor(type: ComputeNodeType, id: string, formId: number) {
+        super(type, id, FieldType.Input, formId);
     }
 
     public getValue() {
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 3c5a5d761591b87c00737762eff283123722dcad..3818a9b72e5bdb4dbc68095bf4d4d2828a0c30c8 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -36,8 +36,8 @@ export class NgParameter extends InputField {
     public maxValue: number; // valeur max dans le cas ParamRadioConfig.VAR
     public stepValue: number; // pas de progression dans le cas ParamRadioConfig.VAR
 
-    constructor(private _paramDef: ParamDefinition) {
-        super(_paramDef.computeNodeType, _paramDef.symbol);
+    constructor(private _paramDef: ParamDefinition, formId: number) {
+        super(_paramDef.computeNodeType, _paramDef.symbol, formId);
         switch (this._paramDef.getDomain().domain) {
             case ParamDomainValue.ANY:
                 this.minValue = -10;
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index 812b4b11955b40a433221247dc738eb28fe2e787..112e708a9434697ab8634a2e74781e3aac72028c 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -18,8 +18,8 @@ export class SelectField extends Field {
         return this._entries;
     }
 
-    constructor(nodeType: ComputeNodeType, id: string) {
-        super(nodeType, id, FieldType.Select);
+    constructor(nodeType: ComputeNodeType, id: string, formId: number) {
+        super(nodeType, id, FieldType.Select, formId);
         this._entries = [];
     }
 
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index c7e946d7c8c02163ae219a5aa706e35e9f690783..270d1c0e84bbe33d818c52ed3485daa6b221872e 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -8,6 +8,7 @@ import { HttpService } from "../../services/http/http.service";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { FormulaireDefinition, CalculatorType } from "../../formulaire/formulaire-definition";
 import { FormulaireElement } from "../../formulaire/formulaire-element";
+import { InputField } from "../../formulaire/input-field";
 import { SelectField } from "../../formulaire/select-field";
 import { CheckField } from "../../formulaire/check-field";
 import { StringMap } from "../../stringmap";
@@ -118,30 +119,25 @@ export class FormulaireService extends Observable {
         throw "FormulaireService.getFormulaire() : unkown form id " + uid;
     }
 
+    public getInputField(formId: number, elemId: string): InputField {
+        let s = this.getFormulaireElementById(formId, elemId);
+        if (!(s instanceof InputField))
+            throw "Form element with id '" + elemId + "' is not an input";
+        return <InputField>s;
+    }
+
     public getCheckField(formId: number, elemId: string): CheckField {
-        for (let f of this._formulaires)
-            if (f.uid == formId) {
-                let s = f.getFormulaireElementById(elemId);
-                if (s != undefined) {
-                    if (!(s instanceof CheckField))
-                        throw "Form element with id '" + elemId + "' is not a checkbox";
-                    return <CheckField>s;
-                }
-            }
-        return undefined;
+        let s = this.getFormulaireElementById(formId, elemId);
+        if (!(s instanceof CheckField))
+            throw "Form element with id '" + elemId + "' is not a checkbox";
+        return <CheckField>s;
     }
 
     public getSelectField(formId: number, elemId: string): SelectField {
-        for (let f of this._formulaires)
-            if (f.uid == formId) {
-                let s = f.getFormulaireElementById(elemId);
-                if (s != undefined) {
-                    if (!(s instanceof SelectField))
-                        throw "Form element with id '" + elemId + "' is not a select";
-                    return <SelectField>s;
-                }
-            }
-        return undefined;
+        let s = this.getFormulaireElementById(formId, elemId);
+        if (!(s instanceof SelectField))
+            throw "Form element with id '" + elemId + "' is not a select";
+        return <SelectField>s;
     }
 
     private getFormulaireElementById(formId: number, elemId: string): FormulaireElement {
diff --git a/src/app/services/observer.ts b/src/app/services/observer.ts
index 8933a7c60f2430d9f4f56f15487d6c07f740a358..b0c8e943f1581866263db8b14c304deb8fda5096 100644
--- a/src/app/services/observer.ts
+++ b/src/app/services/observer.ts
@@ -3,7 +3,6 @@ export interface Observer {
 }
 
 export class Observable {
-
     private _observers: Observer[];
 
     constructor() {
@@ -11,7 +10,12 @@ export class Observable {
     }
 
     public addObserver(o: Observer) {
-        this._observers.push(o);
+        if (!this._observers.includes(o))
+            this._observers.push(o);
+    }
+
+    public removeObserver(o: Observer) {
+        this._observers = this._observers.filter(a => a !== o);
     }
 
     public notifyObservers(data: any) {
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index a7ccb3a8e3696de0799995443825a2f5200e0713..2eeac9c2975909eb5abc5f5fb48c8513ddc03063 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -1,13 +1,10 @@
-import {
-    ParamDomain, ComputeNodeType, ComputeNodeParameters, ParamsEquation, ParamsSectionRectang, ParamDefinition,
-    ParamDomainValue, ParamCalculability
-} from "jalhyd";
+import { ParamDomain, ComputeNodeType, ComputeNodeParameters, ParamsEquation, ParamDefinition, ParamDomainValue, ParamCalculability } from "jalhyd";
 
 import { NgParameter } from "../../formulaire/ngparam";
 import { logObject } from "../../util";
 
 export class ParamService {
-    private _params: NgParameter[];
+    private _params: ParamDefinition[];
 
     constructor() {
         this._params = [];
@@ -53,18 +50,9 @@ export class ParamService {
         // logObject(this._params);
     }
 
-    private hasParameter(prm: ParamDefinition): boolean {
-        for (let p of this._params)
-            // if (p.computeNodeType == prm.computeNodeType && (p.symbol == prm.symbol || p.alias == prm.symbol))
-            if (p.computeNodeType == prm.computeNodeType && p.symbol == prm.symbol)
-                return true;
-
-        return false;
-    }
-
     private addParameter(p: ParamDefinition) {
-        if (!this.hasParameter(p))
-            this._params.push(new NgParameter(p));
+        if (!this.hasParameter(p.computeNodeType, p.symbol))
+            this._params.push(p);
     }
 
     private addParameters(nodeType: ComputeNodeType) {
@@ -75,7 +63,12 @@ export class ParamService {
         }
     }
 
-    public getParameter(nodeType: ComputeNodeType, symbol: string): NgParameter {
+    /**
+     * vérifie si un noeud possède un paramètre donné
+     * @param nodeType type de noeud
+     * @param symbol symbole à vérifier
+     */
+    private hasParameter(nodeType: ComputeNodeType, symbol: string): ParamDefinition {
         for (let p of this._params)
             if (p.computeNodeType == nodeType && p.symbol == symbol)
                 return p;
@@ -85,22 +78,30 @@ export class ParamService {
             case ComputeNodeType.SectionPuissance:
             case ComputeNodeType.SectionRectangle:
             case ComputeNodeType.SectionTrapeze:
-                return this.getParameter(ComputeNodeType.SectionParametree, symbol);
+                return this.hasParameter(ComputeNodeType.SectionParametree, symbol);
 
             case ComputeNodeType.RegimeUniformeCercle:
             case ComputeNodeType.RegimeUniformePuissance:
             case ComputeNodeType.RegimeUniformeRectangle:
             case ComputeNodeType.RegimeUniformeTrapeze:
-                return this.getParameter(ComputeNodeType.RegimeUniforme, symbol);
+                return this.hasParameter(ComputeNodeType.RegimeUniforme, symbol);
 
             case ComputeNodeType.CourbeRemousCercle:
             case ComputeNodeType.CourbeRemousPuissance:
             case ComputeNodeType.CourbeRemousRectangle:
             case ComputeNodeType.CourbeRemousTrapeze:
-                return this.getParameter(ComputeNodeType.CourbeRemous, symbol);
+                return this.hasParameter(ComputeNodeType.CourbeRemous, symbol);
 
             default:
                 return undefined;
         }
     }
+
+    public createParameter(nodeType: ComputeNodeType, symbol: string, formId: number): NgParameter {
+        let prmDef: ParamDefinition = this.hasParameter(nodeType, symbol);
+        if (prmDef == undefined)
+            throw "ParamService.createParameter() : pas de paramètre '" + symbol + "' pour le type de noeud " + ComputeNodeType[nodeType];
+
+        return new NgParameter(prmDef.clone(), formId);
+    }
 }