Skip to content

Commit 7899780

Browse files
author
Vlad Balin
committed
updated docs
1 parent 4e68974 commit 7899780

File tree

2 files changed

+209
-0
lines changed

2 files changed

+209
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,5 @@ attributes : {
209209
```
210210
It can be accessed as a part of state, however, `link.requestChanges` will be call on assignment
211211
instead of state modification. Its value will be updated automatically when component will receive new props.
212+
213+
[Guide to Data Binding Use Cases](/example/databinding.md)

example/databinding.md

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Data binding examples
2+
3+
Here are the set of examples for typical `nestedreact` data binding use cases.
4+
5+
## Checkboxes
6+
7+
Standard `<input/>` will work. Custom Checkbox component might be implemented like this:
8+
9+
```javascript
10+
const Checkbox = ({ className = 'checkbox', checkedLink }) => (
11+
<div className={ className + ( checkedLink.val() ? ' selected' : '' ) }
12+
onClick = { checkedLink.update( x => !x ) }
13+
/>
14+
);
15+
```
16+
17+
Examples will assume working with custom Checkbox.
18+
19+
### Binding to boolean model attributes
20+
21+
```javascript
22+
import { Model } from 'nestedtypes'
23+
24+
const MyModel = Model
25+
.defaults({
26+
option1 : true,
27+
option2 : false
28+
});
29+
30+
const CheckboxGroup = ({ model /* instanceof MyModel */ }) => (
31+
<div>
32+
<div>
33+
<Checkbox checkedLink={ model.getLink( 'option1' ) } />
34+
Option 1
35+
</div>
36+
<div>
37+
<Checkbox checkedLink={ model.getLink( 'option2' ) } />
38+
Option 2
39+
</div>
40+
</div>
41+
);
42+
```
43+
44+
### Binding to array of selected options
45+
46+
```javascript
47+
import { Model } from 'nestedtypes'
48+
49+
const MyModel = Model
50+
.defaults({
51+
options : [ 'option1' ]
52+
});
53+
54+
const CheckboxGroup = ({ model /* instanceof MyModel */ }) => {
55+
const link = model.getLink( 'options' );
56+
57+
return (
58+
<div>
59+
<div>
60+
<Checkbox checkedLink={ link.contains( 'option1' ) } />
61+
Option 1
62+
</div>
63+
<div>
64+
<Checkbox checkedLink={ link.contains( 'option2' ) } />
65+
Option 2
66+
</div>
67+
</div>
68+
);
69+
};
70+
```
71+
72+
### Binding to collection of selected models
73+
74+
```javascript
75+
import { Model } from 'nestedtypes'
76+
77+
const MyModel = Model
78+
.defaults({
79+
all : Some.Collection,
80+
selected : Collection.subsetOf( 'all' )
81+
});
82+
83+
const CheckboxGroup = ({ model /* instanceof MyModel */ }) => {
84+
const { all, selected } = model;
85+
86+
return (
87+
<div>
88+
{ all.map( model => (
89+
<div>
90+
<Checkbox checkedLink={ selected.getLink( model ) } />
91+
{ model.displayName }
92+
</div>
93+
))}
94+
</div>
95+
);
96+
};
97+
```
98+
99+
## Radio Groups
100+
101+
For the radio groups you will need custom Radio component. It's very similar to custom Checkbox one,
102+
with one difference in click handler:
103+
104+
```javascript
105+
const Radio = ({ className = 'radio', checkedLink }) => (
106+
<div className={ className + ( checkedLink.val() ? ' selected' : '' ) }
107+
onClick = { checkedLink.update( () => true ) }
108+
/>
109+
);
110+
```
111+
112+
In this example, we bind radio to string values. It's not required for them to be strings.
113+
114+
```javascript
115+
import { Model } from 'nestedtypes'
116+
117+
const MyModel = Model
118+
.defaults({
119+
option : 'option1'
120+
});
121+
122+
const RadioGroup = ({ model /* instanceof MyModel */ }) => {
123+
const link = model.getLink( 'option' );
124+
125+
return (
126+
<div>
127+
<div>
128+
<Radio checkedLink={ link.equals( 'option1' ) } />
129+
Option 1
130+
</div>
131+
<div>
132+
<Radio checkedLink={ link.equals( 'option2' ) } />
133+
Option 2
134+
</div>
135+
</div>
136+
);
137+
};
138+
```
139+
140+
## Input fields
141+
142+
Standard `<input>` will work. You may implement custom input controls to handle complex scenarios
143+
with validation and appearance.
144+
145+
```javascript
146+
const Input = ({ valueLink, ...props }) => (
147+
<div className='wrapping'
148+
<input {...props} value={ valueLink.val() } onChange={ e => valueLink.val( e.target.value ) }/>
149+
</div>
150+
);
151+
```
152+
153+
### Binding to model attributes
154+
155+
```javascript
156+
import { Model } from 'nestedtypes'
157+
158+
const MyModel = Model
159+
.defaults({
160+
number : 0,
161+
string : ''
162+
});
163+
164+
const InputGroup = ({ model /* instanceof MyModel */ }) => (
165+
<div>
166+
<label>
167+
Number:
168+
<input type='number' valueLink={ model.getLink( 'number' ) } />
169+
</label>
170+
<label>
171+
String:
172+
<input valueLink={ model.getLink( 'string' ) } />
173+
</label>
174+
</div>
175+
);
176+
};
177+
```
178+
179+
### Binding to an array of strings
180+
181+
The same technique may be used to bind to an array or hash of strings. First, take a link to this
182+
attribute. Next, use `link.map` method to iterate through elements links created for you.
183+
184+
`link.map` will internally execute `link.at( key )` method to create a link to the plain object or array element.
185+
These methods may be used manually to create binding for the structures of any particular depth and complexity.
186+
187+
However, for the JS data with known structure it's recommended to wrap them in models.
188+
189+
```javascript
190+
import { Model } from 'nestedtypes'
191+
192+
const MyModel = Model
193+
.defaults({
194+
strings : [ 'first', 'second' ]
195+
});
196+
197+
const InputGroup = ({ model /* instanceof MyModel */ }) => (
198+
<div>
199+
{ model.getLink( 'strings' ).map( strLink => (
200+
<div>
201+
<input type='number' valueLink={ strLink } />
202+
</div>
203+
)) }
204+
</div>
205+
);
206+
};
207+
```

0 commit comments

Comments
 (0)