Skip to content

Commit d123cd8

Browse files
author
Vlad Balin
committed
Improved purely functional updates
1 parent 50101ba commit d123cd8

File tree

4 files changed

+57
-77
lines changed

4 files changed

+57
-77
lines changed

README.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
Advanced React links for purely functional two-way data binding.
22

3+
React 15.x will remove valueLink support. This package is complete
4+
dependency-free implementation of valueLinks with powerful API extensions.
5+
36
- Implements standard React 0.14 links API
47
- API extensions:
8+
- Purely functional updates of enclosed objects and arrays.
59
- Declarative binding to event handlers.
610
- Simple form validation.
7-
- Link to plain object and array members with pure updates.
8-
- Derivative boolean links for checkbox and radio groups.
9-
- Reference implementation for 'linked' tags:
11+
- Offhand boolean link creation for checkbox and radio groups.
12+
- Reference implementation for 'linked' tags (you'll need it with React 15.x):
1013
- Standard tags: `<Input />` (with validation), `<Select />`, `<TextArea />`
1114
- Custom tags: `<Radio />`, `<Checkbox />`
1215

@@ -24,6 +27,12 @@ var list = linkToArray.map( ( itemLink, i ) => (
2427
> helping you to build large-scale React applications with a powerful and fast [NestedTypes](https://github.com/Volicon/NestedTypes/)
2528
> classical OO models.
2629
30+
# Breaking API changes in version 1.1
31+
32+
- `link.update` is now performs **immediate purely functional link update**, shallow copying enclosed plain objects and arrays.
33+
- `link.action` behaves as `link.update` in 1.x. **Rename**.
34+
- `link.toggle` is removed. Use `link.update( x => !x )` instead.
35+
2736
# Installation
2837

2938
`npm install valuelink`
@@ -62,10 +71,17 @@ import { Input } from 'valuelink/tags.jsx'
6271
<button onClick={ () => boolLink.set( !boolLink.value ) } />
6372
```
6473
65-
- Update link value: `link.update( prevValue => newValue )`
74+
- Purely functional link value: `link.update( prevValue => newValue )`.
75+
Plain objects and arrays are shallow copied by `update` and `action` functions,
76+
thus it's safe just to update the value in place.
6677

6778
```javascript
6879
<button onClick={ () => boolLink.update( x => !x ) } />
80+
<button onClick={ () => objLink.update( obj => {
81+
obj.a = 1;
82+
return obj;
83+
}) } />
84+
6985
```
7086

7187
- Create action to handle UI event: `link.action( ( prevValue, Event ) => newValue )`

app.js

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20321,7 +20321,7 @@
2032120321

2032220322
// Immediately update the link
2032320323
update: function update(transform, e) {
20324-
var nextValue = transform(this.value, e);
20324+
var nextValue = transform(clone(this.value), e);
2032520325
nextValue === void 0 || this.set(nextValue);
2032620326
},
2032720327

@@ -20383,16 +20383,15 @@
2038320383

2038420384
// link to enclosed object or array member
2038520385
at: function at(key) {
20386-
var link = this;
20387-
20388-
return new Link(this.value[key], function (x) {
20389-
if (this.value !== x) {
20390-
var objOrArr = link.value;
20391-
objOrArr = clone(objOrArr);
20392-
objOrArr[key] = x;
20393-
link.set(objOrArr);
20394-
}
20395-
});
20386+
return new NestedLink(this, key);
20387+
/*Link( this.value[ key ], function( x ){
20388+
if( this.value !== x ){
20389+
var objOrArr = link.value;
20390+
objOrArr = clone( objOrArr );
20391+
objOrArr[ key ] = x;
20392+
link.set( objOrArr );
20393+
}
20394+
} );*/
2039620395
},
2039720396

2039820397
// iterates through enclosed object or array, generating set of links
@@ -20415,39 +20414,27 @@
2041520414
}
2041620415
});
2041720416

20418-
function ArrayLink(link, key) {
20417+
function NestedLink(link, key) {
2041920418
this.value = link.value[key];
2042020419
this.parent = link;
2042120420
this.key = key;
2042220421
}
2042320422

20424-
ArrayLink.prototype = _Object$create(Link.prototype, {
20425-
constructor: ArrayLink,
20426-
set: function set(x) {
20427-
if (this.value !== x) {
20428-
var objOrArr = this.parent.value;
20429-
objOrArr = clone(objOrArr);
20430-
objOrArr[this.key] = x;
20431-
this.parent.set(objOrArr);
20432-
}
20433-
},
20434-
20435-
remove: function remove() {
20436-
var proto = objOrArray && Object.getPrototypeOf(objOrArray);
20423+
NestedLink.prototype = _Object$create(Link.prototype);
20424+
NestedLink.prototype.constructor = NestedLink;
20425+
NestedLink.prototype.set = function (x) {
20426+
if (this.value !== x) {
20427+
var key = this.key;
2043720428

20438-
if (proto === Array.prototype) {
20439-
return objOrArray.splice();
20440-
} else if (proto === Object.prototype) {
20441-
var x = {};
20442-
for (var i in objOrArray) x[i] = objOrArray[i];
20443-
return x;
20444-
}
20429+
this.parent.update(function (parent) {
20430+
parent[key] = x;
20431+
return parent;
20432+
});
2044520433
}
20446-
});
20434+
};
2044720435

2044820436
// Tools
2044920437
// ============================================
20450-
2045120438
function mapObject(link, object, fun) {
2045220439
var res = [];
2045320440

app.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.js

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Link.prototype = {
3131

3232
// Immediately update the link
3333
update : function( transform, e ){
34-
var nextValue = transform( this.value, e );
34+
var nextValue = transform( clone( this.value ), e );
3535
nextValue === void 0 || this.set( nextValue );
3636
},
3737

@@ -90,16 +90,7 @@ Link.prototype = {
9090

9191
// link to enclosed object or array member
9292
at : function( key ){
93-
var link = this;
94-
95-
return new Link( this.value[ key ], function( x ){
96-
if( this.value !== x ){
97-
var objOrArr = link.value;
98-
objOrArr = clone( objOrArr );
99-
objOrArr[ key ] = x;
100-
link.set( objOrArr );
101-
}
102-
} );
93+
return new NestedLink( this, key );
10394
},
10495

10596
// iterates through enclosed object or array, generating set of links
@@ -113,41 +104,27 @@ Link.prototype = {
113104
initialize : function( value, set, error ){}
114105
};
115106

116-
117-
function ArrayLink( link, key ){
118-
this.value = link.value[ key ];
107+
function NestedLink( link, key ){
108+
this.value = link.value[ key ];
119109
this.parent = link;
120-
this.key = key;
110+
this.key = key;
121111
}
122112

123-
ArrayLink.prototype = Object.create( Link.prototype, {
124-
constructor : ArrayLink,
125-
set : function( x ){
126-
if( this.value !== x ){
127-
var objOrArr = this.parent.value;
128-
objOrArr = clone( objOrArr );
129-
objOrArr[ this.key ] = x;
130-
this.parent.set( objOrArr );
131-
}
132-
},
113+
NestedLink.prototype = Object.create( Link.prototype );
114+
NestedLink.prototype.constructor = NestedLink;
115+
NestedLink.prototype.set = function( x ){
116+
if( this.value !== x ){
117+
var key = this.key;
133118

134-
remove : function(){
135-
var proto = objOrArray && Object.getPrototypeOf( objOrArray );
136-
137-
if( proto === Array.prototype ){
138-
return objOrArray.splice();
139-
}
140-
else if( proto === Object.prototype ){
141-
var x = {};
142-
for( var i in objOrArray ) x[ i ] = objOrArray[ i ];
143-
return x;
144-
}
119+
this.parent.update( function( parent ){
120+
parent[ key ] = x;
121+
return parent;
122+
} );
145123
}
146-
});
124+
};
147125

148126
// Tools
149127
// ============================================
150-
151128
function mapObject( link, object, fun ){
152129
var res = [];
153130

0 commit comments

Comments
 (0)