Skip to content

Commit 2df05c8

Browse files
author
Vlad Balin
committed
Merge remote-tracking branch 'origin/develop' into develop
Conflicts: README.md
2 parents 7899780 + 0af701e commit 2df05c8

File tree

3 files changed

+244
-3
lines changed

3 files changed

+244
-3
lines changed

README.md.orig

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
# nestedreact
2+
This is React add-on designed to simplify migration to React views in large Backbone applications.
3+
4+
It allows you:
5+
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
11+
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+
14+
# Breaking changes introduced in 0.3
15+
- `component.createView( props )` doesn't work any more, use `new component.View( props )` instead.
16+
- module and `npm` package name is now `nestedreact`.
17+
- Raw `backbone` is not supported any more. Upgrade to `NestedTypes` 1.1.5 or more is required. It will give you following
18+
features to help managing complex application state:
19+
- Proper nested models and collections implementation with deep changes detection. React components will
20+
update UI on nested attribute changes.
21+
- Dramatic improvement in model update performance compared to Backbone. Up to 40x faster in Chrome. Important for mobile devices.
22+
- Type safety. Attributes are guaranteed to hold values of declared types all the time.
23+
24+
For more information about `NestedTypes`, visit
25+
http://volicon.github.io/backbone.nestedTypes/
26+
and
27+
https://github.com/Volicon/backbone.nestedTypes
28+
29+
# Usage
30+
It's packed as single UMD, thus grab the module or use `npm` to install.
31+
`npm install --save nestedreact`
32+
33+
Module export's modified React namespace (without touching original React), and its
34+
safe to use it as a replacement for `react`.
35+
36+
If you're using backbone-based frameworks such as `ChaplinJS` or `Marionette`,
37+
you need to do following things:
38+
- Make sure that frameworks includes `nestedtypes` instead of `backbone`.
39+
- On application start, tell `nestedreact` to use proper base class for View.
40+
`require( 'nestedreact' ).useView( Chaplin.View )`
41+
42+
# Features
43+
## Use React components as Backbone View
44+
45+
```javscript
46+
var backboneView = new MyReactComponent.View( props );
47+
```
48+
49+
## Use Backbone View in React component
50+
51+
```javscript
52+
var React = require( 'nestedreact' );
53+
54+
var MyComponent = React.createClass({
55+
render : function(){
56+
return (
57+
<div>
58+
<React.subview
59+
className="classes for root element"
60+
View={ BackboneView }
61+
options={ viewOptions }
62+
/>
63+
</div>
64+
);
65+
}
66+
});
67+
```
68+
69+
## Helper methods for easy Backbone to React transition
70+
71+
There are `el`, `$el`, and `$( selector )` available for the React components,
72+
which simplifies refactoring of the existing event handlers and usage of
73+
`jquery` plugins.
74+
75+
```javscript
76+
var React = require( 'nestedreact' );
77+
78+
var MyComponent = React.createClass({
79+
onClick : function(){
80+
this.$( '#somewhere' ).html( 'Hi' );
81+
}
82+
});
83+
```
84+
85+
It is extremely dangerous and conceptually wrong to directly *modify existing*
86+
DOM subtree in React component. Read is safe, modify DOM when you know what you're
87+
doing. Lets say, integrating `jQuery` plugins.
88+
89+
*You must not use these methods in render*. `jquery` plugins can be initialized
90+
in `componentDidMount` method or in event handlers.
91+
92+
## Use Existing Backbone Model as component's state
93+
94+
```javscript
95+
var React = require( 'nestedreact' );
96+
97+
var MyComponent = React.createClass({
98+
Model : BackboneModel,
99+
100+
render : function(){
101+
return (
102+
<div onClick={ this.onClick }>
103+
{ this.state.count }
104+
</div>
105+
);
106+
},
107+
108+
onClick : function(){
109+
this.state.count = this.state.count + 1;
110+
}
111+
});
112+
```
113+
114+
If Model is specified for the component,
115+
- `this.state` and `this.model` holds backbone model. Usage of `setState` is *not allowed*.
116+
- React component will update itself whenever model emit `change` event.
117+
- You can customize UI update events supplying `listenToState` property. For example, `listenToState : 'change:attr sync'`.
118+
- You can disable UI updates on state change, supplying `listenToState : false` option.
119+
120+
## Managing state with ad-hoc Backbone model
121+
122+
```javscript
123+
var React = require( 'nestedreact' );
124+
125+
var MyComponent = React.createClass({
126+
//Model : BackboneModel,
127+
128+
attributes : { // Model defaults
129+
count : 0
130+
},
131+
132+
render : function(){
133+
return (
134+
<div onClick={ this.onClick }>
135+
{ this.state.count }
136+
</div>
137+
);
138+
},
139+
140+
onClick : function(){
141+
this.state.count = this.state.count + 1;
142+
}
143+
});
144+
```
145+
146+
- New `NestedTypes` Model definition will be created, using `attributes` as Model.defaults.
147+
- If Model property is specified, it will be used as base model and extended.
148+
- `attributes` property from mixins will be properly merged.
149+
- Since `state` is `NestedTypes` model in this case,
150+
- All attributes *must* be declared using `NestedTypes` standard type specs.
151+
- `state` attributes allows direct assignments - treat it as regular object.
152+
- Every `state` modification (including direct assignments and nested attributes changes) will
153+
cause automagical react update.
154+
155+
## Passing Backbone objects as React components props
156+
```javscript
157+
var MyComponent = React.createClass({
158+
listenToProps : { // or just string with property names, separated by space
159+
model : 'change'
160+
},
161+
162+
render : function(){
163+
return (
164+
<div onClick={ this.onClick }>
165+
{ this.props.model.count }
166+
</div>
167+
);
168+
},
169+
170+
onClick : function(){
171+
this.props.model.count = this.props.model.count + 1;
172+
}
173+
});
174+
```
175+
176+
You can update react component on backbone events from component props.
177+
Event subscription is managed automatically. No props passed - no problems.
178+
179+
## Data binding
180+
181+
`nestedreact` supports data binding links compatible with standard React's `valueLink`.
182+
Links are "live" in a sense that they always point to actual value based on current model or collection state.
183+
It doesn't break anything in React, rather extends possible use cases.
184+
185+
- `var link = model.getLink( 'attr' )` creates link for model attribute.
186+
- `var link = collection.getLink( model )` creates boolean link, toggling model in collection. True if model is contained in collection, assignments will add/remove given model. Useful for checkboxes.
187+
188+
### Value access methods
189+
190+
In addition to standard members `link.requestChange( x )` and `link.value`, links supports all popular property access styles:
191+
192+
- jQuery property style: setter `link.val( x )`, getter `link.val()`
193+
- Backbone style: setter `link.set( x )`, getter `link.get()`
194+
- plain assugnments style: setter `link.value = x`, getter `link.value`
195+
- `link.toggle()` is a shortcut for `link.requestChange( !link.value )`
196+
197+
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.
198+
199+
### Link transformations
200+
201+
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.
202+
203+
For links with any value type:
204+
205+
- `link.equals( x )` creates boolean link which is true whenever link value is equal to x. Useful for radio groups.
206+
- `link.update( x => !x )` creates function transforming link value (toggling boolean value in this case). Useful for `onClick` event handlers.
207+
208+
For link enclosing array:
209+
210+
- `arrLink.contains( x )` creates boolean link which is true whenever x is contained in an array in link value. Useful for checkboxes. Avoid long arrays, currently operations has O(N^2) complexity.
211+
212+
For link enclosings arrays and plain JS objects:
213+
- `arrOrObjLink.at( key )` creates link to array of object member with a given key. Can be applied multiple times to work with object hierarchies; on modifications, objects will be updated in purely functional way (modified parts will be shallow copied). Useful when working with plain JS objects in model attributes - updating them through links make changes visible to the model.
214+
- `arrOrObjLink.map( ( itemLink, key ) => <input key={ key } valieLink={ itemLink } /> )` iterates through object or array, wrapping its elements to links. Useful for JSX transofrmation.
215+
216+
### Links and components state
217+
218+
Link received through component props can be mapped as state member using the following declaration:
219+
```javascript
220+
attributes : {
221+
selected : Nested.link( '^props.selectedLink' )
222+
}
223+
```
224+
<<<<<<< HEAD
225+
It can be accessed as a part of state, however, `link.requestChanges` will be call on assignment
226+
instead of state modification. Its value will be updated automatically when component will receive new props.
227+
228+
[Guide to Data Binding Use Cases](/example/databinding.md)
229+
=======
230+
It can be accessed as a part of state, however, in this case it's not true state. All read/write operations will be done with link itself, and local state won't be modified.
231+
232+
Also, links can be used to declaratively expose real component state to upper conponents. In this example, link optionally received in props will be updated every time `this.state.selected` object is replaced. In this case, updates are one way, from bottom component to upper one, and stateful component will render itself when state is changed.
233+
234+
```javascript
235+
attributes : {
236+
selected : Item.has.watcher( '^props.selectedLink.val' )
237+
}
238+
```
239+
240+
Technically, "watcher" - is just a callback function with a single argument receiving new attribute value, so links are not required here.
241+
>>>>>>> origin/develop

0 commit comments

Comments
 (0)