Skip to content

Commit b200eb6

Browse files
author
Vlad Balin
committed
Merge branch 'master' into develop
2 parents f714bb4 + 5a35e94 commit b200eb6

File tree

3 files changed

+105
-12
lines changed

3 files changed

+105
-12
lines changed

README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
# nestedreact
2-
This is React add-on designed to simplify migration to React views in large Backbone applications.
1+
# NestedReact
2+
This is React add-on providing advanced state management to React applications and convergence layer for intermixing React components and Backbone Views.
33

4-
It allows you:
4+
Brief feature list:
55

6-
- To use React component in place of every Backbone View.
7-
- To use your existing Backbone Views from React components.
8-
- To use your existing Backbone Models as React component state.
9-
- Update React components on Backbone events.
10-
- Data-binding for models and collections
6+
- Advanced component's state management with [NestedTypes](https://github.com/Volicon/backbone.nestedTypes).
7+
- Comprehensive two-way data binding - [Guide to Data Binding Use Cases](/example/databinding.md)
8+
- Transparent interoperation with Backbone Views:
9+
- React component can be used as backbone View. `new MyComponent.View({ props })`
10+
- Backbone Views can be used as React components. `<React.subview View={ MyView } />`
11+
- Simplified refactoring of Backbone Views to React components. `this.$`, `this.$el`, `this.$( sel )`, `this.model` works for React components too, as well as `this.trigger` and `this.listenTo`.
1112

12-
Thus, no refactoring of your application is required. You can start writing UI with React immediately replacing your Backbone Views one-by-one, while keeping your existing models.
13+
Thus, if you have Bakcbone application and want to start writing with React - you have no excuses any more. Wanna keep some of your cool Views? They works just fine? Keep 'em. And use them in yout new components, written with React, which you will use in other Backbone Views.
1314

1415
# Breaking changes introduced in 0.3
1516
- `component.createView( props )` doesn't work any more, use `new component.View( props )` instead.
@@ -196,6 +197,9 @@ In addition to standard members `link.requestChange( x )` and `link.value`, link
196197

197198
Most efficient way to work with link is using `link.val()` function, that's how its internally implemented. `val` function is bound, and can be passed around safely.
198199

200+
Here's a brief reference for liks API. Consult [Guide to Data Binding Use Cases](/example/databinding.md) to understand how to use it.
201+
202+
199203
### Link transformations
200204

201205
Attribute's link can be further transformed using extended link API. Link transformations allowing you to use new `stateless functions` component definition style introduced in React 0.14 in most cases.
@@ -232,5 +236,3 @@ attributes : {
232236
```
233237

234238
Technically, "watcher" - is just a callback function with a single argument receiving new attribute value, so links are not required here.
235-
236-
[Guide to Data Binding Use Cases](/example/databinding.md)

example/databinding.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
Here are the set of examples for typical `nestedreact` data binding use cases.
44

5+
Each section contains custom databound component, model definitions, and usage examples.
6+
7+
Somewhere at the top level component(s) there must be the declaration linking model updates to UI. Either models must be (nested) members of some component's state (which will update UI even in case of deep changes), or you may link component updates to changes of models and collections passed in props. In the last case, you will need to add following line to top or middle-level component definition:
8+
9+
```
10+
listenToProps : 'myModel myCollection'
11+
```
12+
13+
It's generally advised to keep stateful components at the top level, and use `listenToProps` in the middle level for optimization purposes if you want local updates. Keep you bottom-level components pure, and try to do the same for the most of your middle level (`listenToProps` used wisely won't hurt). For further information on this topic consult the top-level guide.
14+
515
## Checkboxes
616

717
Standard `<input/>` will work. Custom Checkbox component might be implemented like this:
@@ -204,4 +214,4 @@ const InputGroup = ({ model /* instanceof MyModel */ }) => (
204214
</div>
205215
);
206216
};
207-
```
217+
```

example/todolist.jsx

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React from 'nestedreact'
2+
import { Model } from 'nestedtypes'
3+
4+
// pre-define model, cause we gonna have recursive definition...
5+
const TodoItem = Model.extend();
6+
7+
TodoItem.define({
8+
defaults : {
9+
done : Boolean,
10+
desc : String,
11+
12+
// this is the tree, with components of the same type...
13+
subitems : TodoItem.Collection
14+
},
15+
16+
remove(){
17+
this.collection.remove( this );
18+
},
19+
20+
addChildren(){
21+
this.subitems.push( new TodoItem() );
22+
},
23+
24+
initialize(){
25+
// Pin these methods, cause we gonna use them as click handlers...
26+
_.bindAll( this, 'remove', 'addChildren' );
27+
28+
// Sync done state with subitems across the tree...
29+
// There won't be loop, 'change' is never fired if there are no actual change.
30+
this.listenTo( this, {
31+
'change:subitems' : () => {
32+
let { subitems } = this;
33+
34+
if( subitems && subitems.length ){
35+
this.done = subitems.every( item => item.done );
36+
}
37+
},
38+
39+
'change:done' : () => {
40+
this.subitems.each( item => item.done = this.done );
41+
}
42+
});
43+
}
44+
});
45+
46+
const App = React.createClass({
47+
// define the state...
48+
attributes : {
49+
// deep changes in this tree structure will be detected,
50+
// and this component will be updated automatically.
51+
todos : TodoItem.Collection
52+
},
53+
54+
render(){
55+
// State is already initialized with default values.
56+
// Now, link the state to components...
57+
return <Checklist todos={ this.state.todos } />;
58+
}
59+
});
60+
61+
// Everything else gonna be stateless...
62+
const Checklist = ({ todos } ) => (
63+
<div className="checklist">
64+
{ todos.map( todo => <ToDo key={ todo.cid } todo={ todo } /> )}
65+
</div>
66+
);
67+
68+
const ToDo = ({ todo }) => (
69+
<div className="todo-item">
70+
<div className='header'>
71+
<input type="checkbox" checkedLink={ todo.getLink( 'done' ) } />
72+
<input type="text" valueLink={ todo.getLink( 'desc' ) } />
73+
<div class='add-children' onClick={ todo.addChildren }> + </div>
74+
<div class='delete' onClick={ todo.remove } > x </div>
75+
</div>
76+
{ todo.subitems.length && <Checklist todos={ todo.subitems } /> }
77+
</div>
78+
);
79+
80+
// Done.
81+
export default App;

0 commit comments

Comments
 (0)