Ein Formular aus einem Deskriptor
Die schreibbaren Properties einer Case Class werden zu Eingabefeldern, ihre Accessoren binden sie an eine Instanz. Das Formular unten ist in deinem Browser genau so gebaut.
Live
Erzeugt, gebunden, typisiert
Ändere ein Feld: Der Accessor schreibt die Instanz, und die Zeile darunter liest sie zurück. Das Altersfeld nimmt nur Zahlen, weil der Property-Typ scala.Int sagt.
Profil-Formular
Drei vars, drei Felder, keines von Hand geschrieben.
- profile
- Profile(Ada,[email protected],36)
scala
case class Profile(var name: String, var email: String, var age: Int)
val descriptor = ReflectMacros.reflectWithAccessors[Profile]
descriptor.getWriteableProperties.foreach { property =>
val accessor = property.accessor.get
val numeric = property.propertyType.typeName == "scala.Int"
textField(property.name, accessor.get(profile).toString, numeric) { value =>
accessor.set(profile, if numeric then value.toIntOption.getOrElse(0) else value)
}
}
Warum es im Browser funktioniert
Keine Laufzeit-Reflection beteiligt
Scala.js hat kein java.lang.reflect. Deskriptor und Accessoren sind zur Compile-Zeit entstanden; das Formular ist gewöhnlicher Code, den eben ein Makro geschrieben hat.
Das Rezept erweitern
Lies eine @Label-Annotation für die Feldbeschriftung statt des Property-Namens.
Wähle das Eingabefeld nach propertyType: eine Checkbox für scala.Boolean, ein Datumsfeld für java.time.LocalDate.
Validiere vor set und behalte den vorigen Wert, wenn eine Umwandlung scheitert.
Nutze getReadableProperties für eine schreibgeschützte Detailansicht derselben Klasse.