Form sample
This commit is contained in:
parent
23c933e6b1
commit
f8d3c9ae82
|
|
@ -8,11 +8,21 @@ class ClientEntity {
|
||||||
ClientEntity({this.name, this.contacts});
|
ClientEntity({this.name, this.contacts});
|
||||||
String name;
|
String name;
|
||||||
List<ContactEntity> contacts;
|
List<ContactEntity> contacts;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (name ?? '') + ': ' + contacts.join(', ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContactEntity {
|
class ContactEntity {
|
||||||
ContactEntity({this.email});
|
ContactEntity({this.email});
|
||||||
String email;
|
String email;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return email ?? '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redux classes
|
// Redux classes
|
||||||
|
|
@ -24,6 +34,11 @@ class AppState {
|
||||||
: client = ClientEntity(
|
: client = ClientEntity(
|
||||||
name: 'Acme Client',
|
name: 'Acme Client',
|
||||||
contacts: [ContactEntity(email: 'test@example.com')]);
|
contacts: [ContactEntity(email: 'test@example.com')]);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return client.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateClient {
|
class UpdateClient {
|
||||||
|
|
@ -34,18 +49,18 @@ class UpdateClient {
|
||||||
class AddContact {}
|
class AddContact {}
|
||||||
|
|
||||||
class UpdateContact {
|
class UpdateContact {
|
||||||
final ContactEntity oldContact;
|
final int index;
|
||||||
final ContactEntity newContact;
|
final String email;
|
||||||
UpdateContact({this.oldContact, this.newContact});
|
UpdateContact({this.index, this.email});
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeleteContact {
|
class DeleteContact {
|
||||||
final String email;
|
final int index;
|
||||||
DeleteContact(this.email);
|
DeleteContact(this.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppState reducer(AppState state, action) {
|
AppState reducer(AppState state, action) {
|
||||||
// In an app you'd most like want to
|
// In an actual app you'd most like want to
|
||||||
// use built_value to rebuild the state
|
// use built_value to rebuild the state
|
||||||
if (action is UpdateClient) {
|
if (action is UpdateClient) {
|
||||||
return AppState(ClientEntity(
|
return AppState(ClientEntity(
|
||||||
|
|
@ -58,15 +73,19 @@ AppState reducer(AppState state, action) {
|
||||||
contacts: []
|
contacts: []
|
||||||
..addAll(state.client.contacts)
|
..addAll(state.client.contacts)
|
||||||
..add(ContactEntity())));
|
..add(ContactEntity())));
|
||||||
} else if (action is DeleteContact) {
|
|
||||||
return AppState(ClientEntity(
|
|
||||||
name: state.client.name,
|
|
||||||
contacts: state.client.contacts.where((contact) => contact.email != action.email).toList(),
|
|
||||||
));
|
|
||||||
} else if (action is UpdateContact) {
|
} else if (action is UpdateContact) {
|
||||||
return AppState(ClientEntity(
|
return AppState(ClientEntity(
|
||||||
name: state.client.name,
|
name: state.client.name,
|
||||||
));
|
contacts: []
|
||||||
|
..addAll(state.client.contacts)
|
||||||
|
..removeAt(action.index)
|
||||||
|
..insert(action.index, ContactEntity(email: action.email))));
|
||||||
|
} else if (action is DeleteContact) {
|
||||||
|
return AppState(ClientEntity(
|
||||||
|
name: state.client.name,
|
||||||
|
contacts: []
|
||||||
|
..addAll(state.client.contacts)
|
||||||
|
..removeAt(action.index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
@ -175,6 +194,13 @@ class _ClientPageState extends State<ClientPage> {
|
||||||
_nameController.addListener(_onChanged);
|
_nameController.addListener(_onChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
var store = StoreProvider.of<AppState>(context);
|
||||||
|
_nameController.text = store.state.client.name;
|
||||||
|
super.didChangeDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_nameController.removeListener(_onChanged);
|
_nameController.removeListener(_onChanged);
|
||||||
|
|
@ -184,13 +210,16 @@ class _ClientPageState extends State<ClientPage> {
|
||||||
|
|
||||||
_onChanged() {
|
_onChanged() {
|
||||||
var name = _nameController.text.trim();
|
var name = _nameController.text.trim();
|
||||||
StoreProvider.of<AppState>(context).dispatch(UpdateClient(name));
|
var store = StoreProvider.of<AppState>(context);
|
||||||
|
if (name != store.state.client.name) {
|
||||||
|
store.dispatch(UpdateClient(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StoreBuilder(builder: (BuildContext context, Store<AppState> store) {
|
return StoreBuilder(builder: (BuildContext context, Store<AppState> store) {
|
||||||
_nameController.text = store.state.client.name;
|
//_nameController.text = store.state.client.name;
|
||||||
|
|
||||||
return FormCard(
|
return FormCard(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|
@ -211,7 +240,9 @@ class ContactsPage extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StoreBuilder(builder: (BuildContext context, Store<AppState> store) {
|
return StoreBuilder(builder: (BuildContext context, Store<AppState> store) {
|
||||||
var contacts = store.state.client.contacts
|
var contacts = store.state.client.contacts
|
||||||
.map((contact) => ContactForm(contact))
|
.map((contact) => ContactForm(
|
||||||
|
contact: contact,
|
||||||
|
index: store.state.client.contacts.indexOf(contact)))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return ListView(
|
return ListView(
|
||||||
|
|
@ -235,7 +266,9 @@ class ContactsPage extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContactForm extends StatefulWidget {
|
class ContactForm extends StatefulWidget {
|
||||||
ContactForm(this.contact);
|
ContactForm({this.contact, this.index});
|
||||||
|
|
||||||
|
final int index;
|
||||||
final ContactEntity contact;
|
final ContactEntity contact;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -251,6 +284,12 @@ class _ContactFormState extends State<ContactForm> {
|
||||||
_emailController.addListener(_onChanged);
|
_emailController.addListener(_onChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
_emailController.text = widget.contact.email;
|
||||||
|
super.didChangeDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_emailController.removeListener(_onChanged);
|
_emailController.removeListener(_onChanged);
|
||||||
|
|
@ -259,8 +298,11 @@ class _ContactFormState extends State<ContactForm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onChanged() {
|
_onChanged() {
|
||||||
var name = _emailController.text.trim();
|
var store = StoreProvider.of<AppState>(context);
|
||||||
//StoreProvider.of<AppState>(context).dispatch(UpdateClient(name));
|
var email = _emailController.text.trim();
|
||||||
|
if (email != widget.contact.email) {
|
||||||
|
store.dispatch(UpdateContact(email: email, index: widget.index));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -270,8 +312,7 @@ class _ContactFormState extends State<ContactForm> {
|
||||||
return FormCard(
|
return FormCard(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
TextFormField(
|
TextFormField(
|
||||||
initialValue: widget.contact.email,
|
controller: _emailController,
|
||||||
//onSaved: (value) => _email = value.trim(),
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Email',
|
labelText: 'Email',
|
||||||
),
|
),
|
||||||
|
|
@ -283,7 +324,7 @@ class _ContactFormState extends State<ContactForm> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 12.0),
|
padding: const EdgeInsets.only(top: 12.0),
|
||||||
child: FlatButton(
|
child: FlatButton(
|
||||||
onPressed: () => store.dispatch(DeleteContact(widget.contact.email)),
|
onPressed: () => store.dispatch(DeleteContact(widget.index)),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Delete',
|
'Delete',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue