Skip to content

Instantly share code, notes, and snippets.

@aaronlademann-wf
Created September 25, 2019 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronlademann-wf/515436c16989efaa7f89cc01e9a90a40 to your computer and use it in GitHub Desktop.
Save aaronlademann-wf/515436c16989efaa7f89cc01e9a90a40 to your computer and use it in GitHub Desktop.
Flux component with store using a serializable model
import 'dart:convert';
class DesignItem {
final String name;
final String id;
final Map meta;
DesignItem(this.name, {String id, this.meta = const {}}) : id = id ?? name;
factory DesignItem.fromString(String fileSrc) {
final fileData = json.decode(fileSrc) as Map;
return DesignItem(fileData['name'], id: fileData['id'], meta: fileData['meta']);
}
/// Makes the class serializable
@override
String toString() => '{id: $id, name: $name, meta: $meta}';
}
class Design {
final String name;
final String id;
final List<DesignItem> items;
final Map meta;
Design(this.name, this.items, {String id, this.meta = const {}}) : id = id ?? name;
factory Design.fromString(String fileSrc) {
final fileData = json.decode(fileSrc) as Map;
final serializedItems = (fileData['items'] as List).cast<Map>();
return Design(fileData['name'],
serializedItems.map((serializedItemData) => DesignItem.fromString(json.encode(serializedItemData))).toList(),
id: fileData['id'],
meta: fileData['meta']);
}
/// Makes the class serializable
@override
String toString() => '{id: $id, name: $name, items: $items, meta: $meta}';
}
import 'dart:html';
import 'package:over_react/over_react.dart';
import 'design_models.dart';
import 'design_view_actions.dart';
import 'design_view_store.dart';
part 'design_view.over_react.g.dart';
@Factory()
UiFactory<DesignViewProps> DesignView = _$DesignView;
@Props()
class _$DesignViewProps extends FluxUiProps<DesignViewActions, DesignViewStore> {}
@Component()
class DesignViewComponent extends FluxUiComponent<DesignViewProps> {
@override
render() {
return (Dom.div()..addProps(copyUnconsumedDomProps()))(
Dom.h4()('Design View'),
Dom.ul()(
props.store.design.items.map(_renderItem).toList(),
),
Dom.div()(
(Dom.label()..htmlFor = 'fileUpload')(
'Upload a Design .json File',
),
(Dom.input()
..name = 'fileUpload'
..type = 'file'
..accept = 'json'
..multiple = false
..onChange = _handleFileUpload
)(),
),
);
}
ReactElement _renderItem(DesignItem model) {
return (Dom.li()..key = model.id)(
model.name,
_renderItemMeta(model),
);
}
ReactElement _renderItemMeta(DesignItem model) {
if (model.meta.isEmpty) return null;
final itemMetaItems = <ReactElement>[];
for (var key in model.meta.keys) {
itemMetaItems.add(
(Dom.li()..key = key)(
'$key: ${model.meta[key]}',
)
);
}
return Dom.ul()(
itemMetaItems,
);
}
_handleFileUpload(SyntheticEvent event) {
final fileInputNode = event.target as FileUploadInputElement;
final fileReader = FileReader()..readAsText(fileInputNode.files.single);
fileReader.onLoadEnd.listen((_) {
props.actions.setDesign(Design.fromString(fileReader.result));
});
}
}
import 'package:w_flux/w_flux.dart';
import 'design_models.dart';
class DesignViewActions {
final setDesign = new Action<Design>();
}
import 'package:w_flux/w_flux.dart';
import 'design_models.dart';
import 'design_view_actions.dart';
class DesignViewStore extends Store {
DesignViewStore(this._actions, {Design initialDesign}) {
_design = initialDesign ?? Design('The initial design', [
DesignItem('The first item of the initial design', meta: {'foo': 'bar', 'some_other_key': 'value'}),
DesignItem('The second item of the initial design'),
DesignItem('The third item of the initial design'),
]);
_actions.setDesign.listen(_setDesign);
}
Design _design;
Design get design => _design;
DesignViewActions _actions;
void _setDesign(Design newDesign) {
_design = newDesign;
trigger();
}
}
import 'dart:html';
import 'package:over_react/over_react.dart';
import 'package:over_react/react_dom.dart' as react_dom;
import 'design_view.dart';
import 'design_view_actions.dart';
import 'design_view_store.dart';
main() {
setClientConfiguration();
final actions = new DesignViewActions();
final store = new DesignViewStore(actions);
react_dom.render((DesignView()
..actions = actions
..store = store
)(), querySelector('#main'));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment