ReactiveObjects
Add reactivity to your objects
In Meteor we have a lot of near magical tools that automatically update the DOM and rerun our functions. Some examples you may know are Meteor.Collections and Sessions variables. Now you can easily get the same reactive goodness in your objects.
Breaking Changes!!!
- As of v0.8.1 this package is built for meteor v0.9.0+
- As of v0.7.1 the api has completely changed. To use the old api reference tag v0.6.0
- As of v0.8.0 this package is no longer a Behave behavior (because that was a bad idea, sorry)
Technobabble
ReactiveObjects creates objects with clean reactive properties, via ECMA-262 [[get]] / [[set]] standards.
ReactiveObjects sets up Deps dependancies inside the setProperty function.
This means every time you update a reactive property in an object it will trigger a invalidation.
This "automatically rerun[s] templates and other computations" (Meteor Docs) as well as Deps.autorun().
This package now uses proxies that can wrap object mutation functions.
For example Array.push()
will can Deps changed()
1//create a module scope 2 3//create an instance with a reactive property 4reactiveObjectInstance = new ReactiveObjects({'reactiveProp': 'foo') 5reactiveObjectInstance.reactiveProp 6=> 'foo' //this is now a reactive property. 7 8//Its still an normal object 9reactiveObjectInstance.normalProp = 'some string' 10=> 'some string' //not a reactive property 11 12//You can always add more reactive properties 13reactiveObjectInstance.ReactiveFunctions.addProperty('otherReactiveProp','bar') 14=> 'bar' //this now exists as a reactive property.
Don't fear the Deps
Ok, that's a lie, you should respect Deps
because it is very powerful.
Before you use this package you should have a good understanding of Deps.
Read the docs and check out EventedMind's Deps videos by Chris Mather:
API
Terms & Concepts
- instance: Is the result of
new ReactiveObject({})
ReactiveObjects.removeProperty(object, property)
- Removes a reactive property form the object and returns the object.
The property is converted back to a standard property with the current value.
- Note: to completely remove a reactive property call this function and then run
delete object.property
ReactiveObjects.removeObject(object)
- Removes reactive properties form the object and returns the object.
The properties are converted back to standard properties with their current values.
- Note: to completely remove the object just call
delete object
ReactiveObjects.isReactiveProperty(object, property)
- Checks if the given property is reactive and returns boolean.
ReactiveObjects.isReactiveObject(object)
- Checks if the object has any reactive properties and returns boolean.
instance.ReactiveFunctions.addProperty(name, value)
- Adds a reactive property to the object and returns the object.
Don't worry about overriding existing properties, defaults are preserved.
instance.ReactiveSettings
This object holds all of your objects reactive properties state data. It contains myProperty value
, type
, deps
value
is the un-mutated value of the property. If you need to work with the value of the properly in a non-reactive way use this viainstance.ReactiveSettings.myProperty.value
type
is what proxy will be used to interface with the propertydeps
is the deps handle for the property.
Proxies
ReactiveObjects does its best not to mutate any values you pass into it. Unfortunately their is no universal way to observe objects changes without overriding its prototype or using wrappers. Proxies are wrappers around existing objects like arrays.
default
Any genaric property that calls depschanged()
onset
and depsdepend()
onget
array
An array proxy that wraps array functions with deps calls.
ReactiveObjects settings
1 ReactiveObjects.dynamicProxies = true //default
dynamicProxies
is a boolean that enables type detection. Currently this just checks to see if the value you added is an array or not. If it is an array it setsinstance.ReactiveSettings.myArray.type = 'array'
. This property will now call on the array proxy. If you want manually control property proxy type then set this to false.
Use Case?
The most obvious usage is reactive templates
1<!-- Lets assume: Template.example.reactiveObject = new ReactiveObject(...) --> 2{{#with ReactiveObject}} 3 {{normalProp}} <!-- someObjectProp --> 4 {{reactiveProp}} <!-- value --> 5 {{otherReactiveProp}} <!-- --> 6{{/with}} 7
Lets change things up
1reactiveObject.normalProp = "not going to react" 2reactiveObject.reactiveProp = "Something Awesome!" 3reactiveObject.otherReactiveProp = 42
1{{#with ReactiveObject}} 2 {{normalProp}} <!-- someObjectProp --> 3 {{reactiveProp}} <!-- Something Awesome! --> 4 {{otherReactiveProp}} <!-- 42 --> 5{{/with}}
Full Spec 'N Test
To see the test run meteor test-packages <path to package>
.
These will always be updated before the readme so if something seems off, run the tests; I will try to keep the doc up-to-date.
This package will not hit 1.0.0 until meteor is 1.0.0. No point in saying its stable when the Deps api may change. That said, the core api work is done. If you want a new feature or, if you want to change the names, please post an issue! I would like to stabilize the api before 1.0.0.