kestanous:reactive-objects

v0.8.2Published 10 years ago

This package has not had recent updates. Please investigate it's current state before committing to using it in your project.

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 via instance.ReactiveSettings.myProperty.value
  • type is what proxy will be used to interface with the property
  • deps 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 deps changed() on set and deps depend() on get
  • 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 sets instance.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 Build Status

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.