2017-10-20 9 views
0

Existe-t-il un moyen de forcer la forme angulaire à recréer ses contrôles? Je veux dire créer de nouvelles instances? On dirait que cela les crée seulement sur la charge initiale. Je ne sais pas si j'en ai vraiment besoin mais voici mon problème:Angulaire 2. Reconstruction de formulaire de reconstruction

J'ai un "edit" contrôle qui a un @Input() set item(editItem) de l'élément que j'ai besoin de modifier. J'ai placé cet élément de son parent et le contrôle devrait remettre à zéro les valeurs de forme. Dans un formulaire, j'utilise mon propre menu déroulant personnalisé qui a une liste d'options pouvant être liées.

En général, il ressemble à ceci:

@Component({ 
    template:` 
    <form [formGroup]="form"> 
     <my-control [items]="items" formControlName="itemId"></app-combobox> 
    </form> 
    ` 

export class EditComponent implements OnInit { 
    items = [{text: 'Item 1', itemId: 1}, {text: 'Item 2', itemId: 2}]; 

    @Input() set editItem(item) { 
    //if some logic... 
     this.items = [{text: 'Item 3', itemId: 3}, {text: 'Item 4', itemId: 4}]; 

    this.initForm(item); 
    } 

    constructor(private _fb: FormBuilder) {} 

    ngOnInit(): void { 
    this.initForm(); 
    } 

    initForm(item?) { 
    this.form = this._fb.group({ 
     // itemId could differ and should be in the items list before binding happens 
     'itemId': [item ? item.itemId : null] 
    } 
} 

et le contrôle:

export class ComboboxComponent implements ControlValueAccessor { 
    items = []; 

    @Input() set items(list[]) { 
    this.items = list; 
    this.updateValue(); 
    } 

    // ControlValueAccessor implementation 
    writeValue(value: any) { 
    this.updateValue(); 
    } 

    updateValue() { 
    // here we try to use a newly updated list (but it's not updated yet!) 
    } 
} 

Et le problème est que même si je place une nouvelle liste des articles avant de créer de nouveaux formGroup la forme de liaison se produit avant la liaison de ma liste d'éléments. La méthode writeValue de l'interface ControlValueAccessor est appelée avant @Input() set items([]) sur mon contrôle déroulant.

Je peux utiliser setTimeout(() => this.updateValue()) à l'intérieur du writeValue et il semble aider mais je n'aime pas cette solution. Comment puis-je faire en sorte que la propriété de contrôle se réalise avant la liaison du formulaire? L'appel de timeout ou forçant Angular à détecter les changements avant que initForm() ne fonctionne pas.

Répondre

0

La façon dont je fais quelque chose de similaire est de mettre en place la structure de forme quelque chose ngOnInit comme ceci:

ngOnInit(): void { 
    this.productForm = this.fb.group({ 
     productName: ['', [Validators.required, 
          Validators.minLength(3), 
          Validators.maxLength(50)]], 
     productCode: ['', Validators.required], 
     starRating: ['', NumberValidators.range(1, 5)], 
     tags: this.fb.array([]), 
     description: '' 
    }); 

Et puis, je ne change pas que lorsque les données changent. Au contraire, mettre à jour uniquement les valeurs sur la forme avec le code comme ceci:

onProductRetrieved(product: IProduct): void { 
    if (this.productForm) { 
     this.productForm.reset(); 
    } 
    this.product = product; 

    // Update the data on the form 
    this.productForm.patchValue({ 
     productName: this.product.productName, 
     productCode: this.product.productCode, 
     starRating: this.product.starRating, 
     description: this.product.description 
    }); 
    this.productForm.setControl('tags', this.fb.array(this.product.tags || [])); 
} 

Vous pouvez appeler cela de votre setter @input.

+0

Merci. Cela ne semble pas fonctionner pour moi ni dur je n'ai pas utilisé fb.array (fait-il de la magie?) Mais a essayé de déplacer mes éléments dans un contrôle de forme et de lier à elle. Les modifications ne sont pas détectées. La seule façon de le faire fonctionner est de référencer la liste déroulante en tant qu'enfant et de définir sa propriété 'items' directement. Ensuite, il se produit immédiatement et avant la liaison de données de formulaire. – rook