2016-12-09 3 views
0

Ich habe ein Redux-Formular, das funktioniert wie es sollte, außer einer Sache: Ich muss ein Array von Kontrollkästchen erstellen, so dass der Benutzer zwischen mehreren Optionen wählen kann.redux-form-array von checkboxes

In HTML/PHP würde man so etwas schreiben:

<form> 
    … 
    <input type="checkbox" name="item[]" value="120" /> 
    <input type="checkbox" name="item[]" value="231" /> 
    … 
</form> 

So auf Server würde man wie so einen Array erhalten (jeweils Feld unter der Annahme geprüft): $item = [120, 231], wobei jedes Element im Array entspricht der Wert des Kontrollkästchens

tut das gleiche mit einer redux-Form wie folgt:

let items = [{name:…, value:…}, …]; 

<form> 
    {items.map(item => { 
    <Field component="input" 
      type="checkbox" 
      name={item.name + '[]'} 
      value={item.value} 
    })} 
</form> 

Ergebnisse in diesen Eingaben: <input type="checkbox" name="item[]" value="true" />, was nicht, was ich erwarten würde. Wenn Sie das Kontrollkästchen aktivieren, wird jedes Array überprüft.

Also änderte ich den Namen Attribut der <Field /> zu

name={`item[${item.value}]`} 

was die Kontrollkästchen macht wie erwartet funktionieren, aber in diesen Daten wiederum Ergebnis, wenn vorgelegt:

{ 
      //index: 0, 1,  ,…, 120, 121, … ,231, …      
    item: [undefinded,undefined,…,true,undefined,…,true,undefined,…] 
} 

Also meine Frage ist : Falsche ich mit der Erstellung der Checkboxen, insbesondere deren Namen, oder muss ich die Daten umwandeln, einmal zur Initialisierungszeit und ein zweites Mal zum Senden?

Wenn ich die Daten transformieren muss, wo wäre der beste Ort dafür?

+0

Wertattribut entfernen. –

Antwort

0

Sie können das Array von Kontrollkästchen/Elementen wie folgt rendern und die aktivierten Kontrollkästchen mit dem Ereignis onChange verfolgen. Verwenden Sie beispielsweise ein Array selectedItems für den Status und fügen Sie Elemente zur Implementierung onItemChange hinzu oder entfernen Sie sie. Auf dem Formularübergabe-Handler haben Sie alle überprüften Elemente im Status verfügbar.

{ 
    items.map((item, index) => { 
    return (
     <div className="checkbox" key={ index }> 
     <label> 
      <input type="checkbox" 
      onChange={ this.onItemChange.bind(this, index) } /> 
      { item.name } 
     </label> 
     </div> 
    ); 
    }) 
} 
+0

Bindung in Render-Funktion ist eine schlechte Übung. Mach im Konstruktor mit. – Anarion

+0

@Anarion Dies ist im Allgemeinen richtig, jedoch in diesem Fall er seine Zuordnung durch ein Array von Elementen und Bindung onItemChange an den Index, um den Eingabewert zu verbrauchen. Dies ist ein allgemeines Muster. – Splitty

+0

@Splitty ist das nicht, was ich vorgeschlagen habe? – Anarion

3

Dies ist, was ich tun endete:

<Field component="input" 
     type="checkbox" 
     name={`item.${item.value}`} /> 

Dieses Sie ein Objekt (und nicht ein Array) als Ausgabedatenstruktur gibt. Es ist nicht ganz das, wonach Sie gefragt haben, aber es ist praktisch (und, IMO, natürlicher als andere Optionen, die das Durchsuchen des Arrays erfordern, wenn ein Wert entfernt werden muss). Statt [120, 231] bekommen Sie

{ 
    120: true, 
    231: true, 
    165: false // be aware that things that have been checked, and then unchecked, will be explicitly marked false 
} 

, wenn Sie es in ein Array umwandeln möchten durch Tasten mit truthy Werte zu finden, das ist eine einfache Sache onSubmit() zu tun. Ich benutze lodash: _.keys(_.pickBy(itemValue)) macht die Konvertierung ganz nett.

+0

Klingt nach einer guten Idee! Ich werde es in einigen Tagen ausprobieren. – philipp