2017-09-28 4 views
2

Ich habe eine reaktive Form, wo ich die Steuerelemente aus meinem Datenmodell erstellen. Anfangs wird alles in numerischer Reihenfolge nach einem Datenpunkt namens "processingOrder" sortiert.Angular reaktive Form versteckter Eingang nicht verbindlich?

In meinem Formulararray verwende ich *ngFor, um über Steuerelemente zu iterieren und den Index in einem versteckten form control zu speichern. Wenn ich einen Datensatz in meiner Tabelle nach oben oder unten verschiebe, sollte der Index, der auf das ausgeblendete Feld angewendet wird, die Änderung in meinem Modell widerspiegeln?

<form [formGroup]="rulesForm" (ngSubmit)="onSubmit(form)"> 
<div formGroupName="ruleData"> 
    <div formArrayName="rules"> 
     <div *ngFor="let child of rulesForm.controls.ruleData.controls.rules.controls; let i = index"> 
     <div formGroupName="{{i}}"> 
      <input type="text" placeholder="Rule Name" formControlName="name"/> &nbsp; 
      <input type="text" placeholder="Rule Description" formControlName="description"/> &nbsp; 
      <input type="text" placeholder="Processing Order" formControlName="processingOrder"/> &nbsp; 
      <button class="button" (click)="move(-1, i)">Move Up</button> &nbsp; 
      <button class="button" (click)="move(1, i)">Move Down</button> 


      <!-- Why doesn't this update my model when it gets a new index? --> 
      <input type="hidden" formControlName="processingOrder" [value]="i"> 


     </div> 
     </div> 
    </div> 
</div> 
<button type="submit">Submit</button> 
</form> 

ich, dass es erhielt in meinem Plunker erwartet hätte, wird die Verarbeitungsreihenfolge-Nummern immer in der 1-5 Reihenfolge bleiben sollten und jedesmal, wenn eine Regel nach oben oder unten, wird das Modell auf den neuen Index aktualisiert .

https://plnkr.co/edit/ZCgHPEaUM00aLxM6Sf9t?p=preview

Antwort

5

formControlName Direktive hat ngModel Eingabe, die an das Modell des Steuerelements gebunden ist, und wenn sie aus dem Code geändert wird, werden alle Instanzen in der Ansicht aktualisiert. So ersetzen Sie einfach [value]="i" mit [ngModel]="i + 1":

<input type="hidden" formControlName="processingOrder" [ngModel]="i + 1"> 

Bindung HTML-Eingabe Eigentum value ([value]="i + 1") werden Stromeingang auf der Ansicht aktualisieren aber nicht die Kontrolle des Modells aktualisieren, damit nicht weitere Instanzen mit der gleichen Steuerung beeinflussen Name.

Sie können auch versteckten Eingang entfernen und [value]="i + 1" auf der Texteingabe:

<input type="text" 
     placeholder="Processing Order" 
     [ngModel]="i + 1" 
     formControlName="processingOrder"/> 

Bitte beachten Sie, dass processingOrder Wert immer von ngFor ‚s Index i

+0

Diese gut zu funktionieren scheint außer Kraft gesetzt werden - Ich habe nur ein kleines Problem, wenn ich eine Regel aus meinem Objekt lösche. Wenn ich vor dem Löschen keine Regeln verschoben habe, bleiben die Regeln bei jeder Entfernung in der richtigen Reihenfolge nach Index. Wenn ich jedoch eine Regel verschiebe und dann eine lösche, dann scheint der Index an der Stelle, an der der Datensatz entfernt wurde, seinen alten Index zu behalten. Ich denke? Am Ende bleiben 2 Datensätze im Objekt mit der gleichen Verarbeitungsreihenfolge. Irgendwelche Gedanken darüber, wie das passieren würde? – SBB

+0

Ich habe Ihren Button mit dem 'Remove' Button aktualisiert, scheint richtig zu funktionieren. Bitte aktualisiere meinen Plocker (https://plnkr.co/edit/NvSkiutOQLeu9i41H1AT?p=preview) damit ich das von dir erwähnte Problem reproduzieren kann, dann werde ich versuchen zu helfen – Andriy

+0

Danke, sieht aus wie mein Problem woanders ist. Das 'ngModel' löste mein Problem jedoch. War nicht bewusst, dass es mit reaktiven Formen verwendet werden könnte. – SBB

0

Fügen Sie diese auf dem Boden der Bewegung nach oben/unten Behandlungsmethode,

move(shift, currentIndex) { 
    const rules = this.rulesForm.get(['ruleData', 'rules']); 

    let newIndex: number = currentIndex + shift; 
    if(newIndex === -1) { 
    newIndex = rules.length - 1; 
    } else if(newIndex == rules.length) { 
    newIndex = 0; 
    } 

    const currentGroup = rules.at(currentIndex); 
    rules.removeAt(currentIndex);; 
    rules.insert(newIndex, currentGroup) 

    // logic to re-calculate processingOrder in the correct ascending order 
    let i = 0; 
    this.rulesForm.get(['ruleData', 'rules']).controls.forEach((elem) => { 
    i++; 
    elem.get('processingOrder').setValue(i); 
    }); 
} 

Es besteht im Wesentlichen die processingOrder Zahlen in aufsteigender Reihenfolge auf der formArray Länge basierend neu zuweist. Ich hoffe es hilft. (Bestätigt, dass es in Plunker funktioniert)

Sie brauchen nicht die input in der Vorlage, damit dies funktioniert. Wenn Sie mehr als ein Eingabesteuerelement angeben (hier Eingabeelemente vom Typ 'text' und 'versteckt' für 'processingOrder') mit derselben formControlName, dann wird es wahrscheinlich nicht so funktionieren, wie Sie es in einem reaktiven Formular erwarten.

Verwandte Themen