2017-06-20 1 views
0

J'ai un composant angulaire "form-fields" qui itère à travers un tableau de types d'entrée basés sur ces types d'entrée, il génère un formulaire. Mon problème est quand je suis en train d'insérer ce composant dans mon formulaire comme suitComment attacher un ngForm à un composant?

<form #form="ngForm" autocomplete="off" novalidate> 
    <form-fields (execFormFieldFunc)="execFormFieldFunc($event)" 
     [formFieldTypes]="templateSelectionItems.formFieldTypes" 
     [formFields]="templateSelectionItems.formFields"> 
    </form-fields> 
    <button class="btn btn-primary" type="button" 
     (click)="templateSelectionFunc(form.value, templateSelectionItems.saveFunc)"> 
     Save 
    </button> 
</form> 

Je suis désireux de joindre un ngForm à la forme des champs de sorte que lorsque je reviens form.value je peux recevoir les valeurs générées à partir des champs de formulaire. Comment puis-je faire cela?

Mettre

<input type="text" id="showme" name="showme" ngModel="themoney" /> inside 

la forme retourne une valeur

{ "showme": "themoney"} composante

Cependant mettre l'entrée à l'intérieur de mes "formulaire champs" ne retourne pas les données.

formFields.component.html

<div *ngFor="let formField of templateSelectionItems.formFields"> 
    <div class="container-fluid col-md-12 col-xs-12"> 
    <div class="row" *ngIf="templateSelectionItems.formFieldTypes[formField.type] !='hidden'">   
    <div class="col-md-3 col-xs-12 space-below">{{formField?.title}}</div> 
    <div class="col-md-3 col-xs-12 space-below"> 
    <span *ngIf="templateSelectionItems.formFieldTypes[formField.type] =='view'">{{formField?.value}}</span> 
    <input *ngIf="templateSelectionItems.formFieldTypes[formField.type]=='number'" type="number" class="form-control" placeholder="{{formField?.placeholder}}"> 
    <input *ngIf="templateSelectionItems.formFieldTypes[formField.type]=='bool'" type="checkbox" class="form-control" checked="{{formField.value}}">     
    </div>    
    </div> 
    <input *ngIf="templateSelectionItems.formFieldTypes[formField.type] == 'view' || templateSelectionItems.formFieldTypes[formField.type] == 'hidden'" type="hidden" name="{{formField.field}}" ngModel="{{formField.value}}"> 
    </div> 
</div> 

Il est prévu de passer le ngForm dans la liste pour être capable de passer en arrière les valeurs de chaque champ de saisie.

Mise à jour: Avant la mise en œuvre ControlValueAccessor

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; 
import { IFormField } from '../common/index' 
import { FormFieldType } from './formFieldTypes.enum'; 

@Component({ 
    selector: 'form-fields', 
    templateUrl: './formFields.component.html' 
}) 

export class FormFieldsComponent implements OnInit {   

@Input() formFields: IFormField[]; 
@Input() formFieldTypes: FormFieldType[];            
@Output() execFormFieldFunc = new EventEmitter(); 

ngOnInit(): void { 

} 

formFieldFunc(data, funcType){   
    var nData = <any>{}; 
    nData.value = data; 
    nData.funcType = funcType; 
    this.execFormFieldFunc.emit(nData); 
} 
} 

Après la mise en œuvre ControlValueAccessor

import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core'; 
import { IFormField } from '../common/index' 
import { FormFieldType } from './formFieldTypes.enum'; 
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; 

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = { 
provide: NG_VALUE_ACCESSOR, 
useExisting: forwardRef(() => FormFieldsComponent), 
multi: true 
}; 

@Component({ 
selector: 'form-fields', 
templateUrl: './formFields.component.html', 
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR] 
}) 

export class FormFieldsComponent implements ControlValueAccessor {   
writeValue(obj: any): void { 
    throw new Error("Method not implemented."); 
} 
registerOnChange(fn: any): void { 
    throw new Error("Method not implemented."); 
} 
registerOnTouched(fn: any): void { 
    throw new Error("Method not implemented."); 
} 
setDisabledState(isDisabled: boolean): void { 
    throw new Error("Method not implemented."); 
} 

@Input() formFields: IFormField[]; 
@Input() formFieldTypes: FormFieldType[];            
@Output() execFormFieldFunc = new EventEmitter(); 

formFieldFunc(data, funcType){   
    var nData = <any>{}; 
    nData.value = data; 
    nData.funcType = funcType; 
    this.execFormFieldFunc.emit(nData); 
} 
} 

Dans sa forme la plus simple

<form #formFields="ngForm"> 
<input type="text" name="text" ngModel="test" /> 
</form> 

œuvres et ci-après ne pas

<form #formFields="ngForm"> 
<form-fields (execFormFieldFunc)="execFormFieldFunc($event)" [formFields]="twoSelects.formFields"></form-fields> 
</form> 

formFields.component.html

<input type="text" name="text" ngModel="test" /> 
+0

'Mettre en oeuvre ControlValueAccessor'? – yurzui

+0

@yurzui Je reçois cette erreur Si ngModel est utilisé dans une balise de formulaire, soit l'attribut de nom doit être défini, soit le contrôle de formulaire doit être défini comme "autonome" dans ngModelOptions. – Demodave

+0

Avez-vous implémenté 'ControlValueAccessor'? Puis ajoutez 'ngModel' et' name' à votre composant – yurzui

Répondre

0

Tout ce que vous devez ajouter est name='{{formField.field}}' l'intérieur balise form:

<div *ngFor="let formField of formFields"> 
    <div class="container-fluid col-md-12 col-xs-12"> 
    <div class="row" *ngIf="formFieldTypes[formField.type] !='hidden'">   
     <div class="col-md-3 col-xs-12 space-below">{{formField?.title}}</div> 
     <div class="col-md-3 col-xs-12 space-below"> 
      <span *ngIf="formFieldTypes[formField.type] =='view'">{{formField?.value}}</span> 
      <input *ngIf="formFieldTypes[formField.type]=='number'" type="number" class="form-control" placeholder="{{formField?.placeholder}}" name='{{formField.field}}'> 
      <input *ngIf="formFieldTypes[formField.type]=='bool'" type="checkbox" class="form-control" checked="{{formField.value}}" ngModel="formField.field" name='{{formField.field}}'>     
     </div>    
    </div> 
    <input *ngIf="formFieldTypes[formField.type] == 'view' || formFieldTypes[formField.type] == 'hidden'" ngModel="formField.field" type="hidden" name='{{formField.field}}'> 
    </div>      
</div> 
+0

Il perd la possibilité de renvoyer ces valeurs de champ à l'intérieur du composant ? – Demodave

+0

avez-vous ajouté name = '{{formField.field}}'?et essayé >> –

+0

s'il vous plaît remplacer mon bloc de code avec le vôtre entièrement, puis réessayez –