When you have a page to create you have to do something like that:
React.createClass({
render() {
<ScrollSpy>
<Child1 />
<Child2 />
<Child3 />
<Child4 />
<Child5 />
</ScrollSpy>
}
});
This component has no state and knows no store.
The state is located in each child and is corellated to the store connection of each Block
.
Eacch block is often done with a FormMixin
.
The formMixin
which should be name formPreset
is composed of the following mixins
ownIdentifierBehaviour
Creates a unique identifier for the form in itsthis
definitionMixin
Connects to the form to the definitions from the model, it allows the component to have a propertydefinitionPath
such asdefinitionPath: 'contact'
referenceBehaviour
which connects the component to the master data lists, it allows the component to have a propertyreferenceNames
in order to detail which master data list you need in your page such asreferenceNames: ['papas', 'monkeys']
.storeBehaviour
connects the component to the stores using the propertystores
which have the signature[{store: aReferenceToTheStore, properties: ['node1', 'node4']}]
such asstores: [{store: contactStore, properties:['contact', 'commandes']}]
it links the components state to the stores changes. Each time a store node is changed, the component state is updated. this behaviour also getstoreChangeBehaviour
which has the_onChange
and_onErrorFunction
validationBehaviour
Add a_validate
method to the form which loops all the components also add a_customValidateMethod
actionBehaviour
add automatic actions to load and save databuiltInComponents
, add all custom components such asfieldFor
,listFor
, ...formMixin
which is the problematic part. It deals with theedit
mode, it has custom methods to render the buttons. It handles the submit of the form, it renders the form and exposesrenderContent
.
const FormExample = React.createClass({
displayName: 'FormExample',
mixins: [formMixin],
stores: [{ // store behaviour + storeChangeBehaviour
store: contactStore,
properties: ['contact', 'commandes']
}],
definitionPath: 'contact', // definitionBehaviour
action: action, // actionBehaviour
referenceNames: ['papas', 'monkeys'], // referenceBehaviour
renderContent() { // formMixin
return (
<Panel actions={this._renderActions} title="Fiche de l'utilisateur">
{this.fieldFor('firstName')}
{this.fieldFor('papaCode', {listName: 'papas'})}
{this.fieldFor('monkeyCode', {listName: 'monkeys', valueKey: 'myCustomCode', labelKey: 'myCustomLabel' })}
{this.fieldFor('lopezCode', {values: [{code: 'JOE', label: 'Joe Lopez'}, {code: 'DAVE', label: 'David Lopez'}]})}
{this.fieldFor('bio')}
{this.fieldFor('isNice')}
{this.textFor('birthDate', {formatter: date => 'formatted date' + date})}
{this.fieldFor('birthDate')}
</Panel>
);
}
});
- The
formMixin
should only be a composition of mixins and it shouldn't add specific code. - When you have an entity which is splitted in two Blocks, even if a block can be connected to multiple store, it is hard to build: the webservices are asymetric between load and save. Its unclear wwhich block load the data.
- The form blocks has all the actions and they are too corelated to it. Actions should no be a part of the form.
- The formMixin has been used for almost every page on each projects. It shouldn't be the case. We thought it will be used as a preset and projects could have customize which part of the formMixin they want in their own presets.
- The formComponent has the state from the store and its sometimes problematic
- The form shouldn't call loading actions
- All the mixins composing the store will be pure, there will be no specific code in the
formMixin
. TheformMixin
is composed of the mixins described in the beginning of this document.
The main goal is to be able to build components without the
formMixin
. Aform-presets
will be published in order to have no regression.
- Actions are decorelated from the components
Solves the problem of an entity
- Fields are stateless and get read it from the parent. The state is located in the parent and only in the parent.
Solves the problem of corelated fields and imporve the testabiliy of the components.
- The connection to the stores will be a wrapper around the component which contains the data.