f / delorean Goto Github PK
View Code? Open in Web Editor NEWAn Agnostic, Complete Flux Architecture Framework
An Agnostic, Complete Flux Architecture Framework
It should have a well-designed webpage with a few demos.
I am proposing to make the data property an official part of the API and define a setState
method as well as make getState
a Store
class defined method. This will allow us to implement a cleaner key-value observing system (automate the emitting of the change
event) as well as other nice-to-have features like default values, computed properties, and standardized way to do data parsing.
I envision the developer would define a definitions
hash like so (excuse the coffeescript, I'm just much faster with it)...
User = Flux.createStore
definitions:
user:
fullName:
default: ''
calculate: ->
"#{@data.user.nameFirst} #{@data.user.nameLast}"
nameFirst:
defualt: ''
nameLast:
default: ''
setUser: (data) ->
@set('user', data) # Automatically emits 'change' event
@getState() # Returns an object with the user property, which has a calced fullName property
every store needs to define a getState
method, so it seem logical to make this a standard method. This will save developers lines of code as well as give them a clean way to create client side only properties.
thoughts? If your interested, I'd be happy to take a first stab at implementing something like this.
The flow diagram is ugly on Readme file. It should be more fancy.
I just ported the React example to Ractive.js.
Looks like DeLorean works with Ractive like a charme out off the box - even without using an Ractive adapter to watch model changes:
There is a scoping issue in the formatScheme
method:
Store.prototype.formatScheme = function (scheme) {
var formattedScheme = {};
for (var keyName in scheme) {
var definition = scheme[keyName], defaultValue, calculatedValue;
defaultValue
and calculatedValue
are not reseted for the next iteration. That is, for in this example:
Flux.createStore({
scheme: {
a: { calculate: function() { ... } },
b: 'foobar'
}
})
the property b
gets the calculate
function from a
.
Using let
instead of var
would solve this issue. However, let
is not yet well supported. I've not made an PR, because I don't know your "style" of handling such scoping things.
Seems like the React fiddle doesn't work
Hi guys!
Can't use delorean with requirejs, because get next error
Uncaught Error: Script error for: requirements.js
http://requirejs.org/docs/errors.html#scripterror
My code snippet
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
baseURI: "/Scripts/Places/Ratings",
paths:
{
delorean: "/bower_components/delorean/dist/delorean"
}
});
require(['delorean'], function(delorean) {
console.log(delorean);
});
</script>```
Please help!
I have multiple nested React components, and in each component I want to access state, so I have the following code:
var MyComponent = React.createClass({
mixins: [Flux.mixins.storeListener],
render: function () {
var mything = this.state.stores.myStore.mything;
:
}
}
If I have this in too many components I get the warning:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Should I increase the limit, or is this not the approach I should take? I can access "global state" as well by doing:
this.stores.myStore.store.mything
but it feels better to access information in the state of the component.
It may have grammatical issues: http://deloreanjs.com/api/delorean.html
In the release in the first line of dist/delorean.js
it says /*! delorean - v0.8.5 - 2014-11-06 */
.
I'm confused. ;)
Hi @f, I've been starting to work on DeLorean. I have a few ideas I'd like to tackle:
dist
folder, since you don't typically want to commit built files.__findDispatcher()
relies on the React view having an attribute, _owner
, to help children find the dispatcher without having to pass it all the way down. My React 13.2 views don't have this attribute. Is it a figment of legacy React? Or is there some trick I'm missing?
The mixin still works provided the dispatcher is passed down on the props of all views needing it, so there is a workaround.
Here's the code:
// `__findDispatcher` is a private function for **React components**.
function __findDispatcher(view) {
// Provide a useful error message if no dispatcher is found in the chain
if (view == null) {
throw 'No dispatcher found. The DeLoreanJS mixin requires a "dispatcher" property to be passed to a component, or one of it\'s ancestors.';
}
/* `view` should be a component instance. If a component don't have
any dispatcher, it tries to find a dispatcher from the parents. */
if (!view.props.dispatcher) {
return __findDispatcher(view._owner);
}
return view.props.dispatcher;
}
Using React 13.2 (13.3 is out but not well described in its changelog)
It's closer to 5k gzipped, which is more relevant than the minified size.
Latest version on NPM is 0.8.5, the docs are related to 0.8.7
Just lost an hour of my day to this ๐ฆ
Yo @darcyadams - I've just updated the NPM package in my project and noticed I'm now getting this:
"You are attempting to create more than one dispatcher. DeLorean is intended to be used with a single dispatcher. This latest dispatcher created will overwrite any previous versions."
Seems like a bit of an anti pattern to me, and IMHO I would expect to use multiple dispatchers to effectively separate any concerns:
A bit of a rigmarole for me, as I have to make sure this is running smoothly on everybody's machines. Will have to rollback to a previous version, and make sure we stay with that.
This seems like a deal breaker :( Could you run me through the design decisions for this?
It may be early but try to use for-of
instead of for-in
loops.
when a store of a dispatcher couldn't update, rollback all stores to the old state.
Using the set method to set keys that are in the scheme it seems as though the data is set on the store object itself, wouldn't it make more sense to have some sort of data object within the store so that these properties aren't mixed in with other methods?
Maybe I'm missing something...
All jsfiddle links seems to be broken and recompiling the example also causes the app to break.
Was this project abandoned?
Hey @darcyadams!
I'll be at army for my military obligation for ~5 months, so I cannot care on project.
Please take care of this project :)
The bower distributed delorean does not work with Require.js
First problem is require('events').EventEmitter
:
module.exports = requirements = {
// DeLorean uses **Node.js native EventEmitter** for event emittion
EventEmitter: require('events').EventEmitter,
// and **es6-promise** for Deferred object management.
Promise: require('es6-promise').Promise
};
But the module is defined as:
module.exports = EventEmitter
So I think in the injector it should just be require('event')
right?
Second problem is in the injector:
// This library needs to work for Browserify and also standalone.
// If DeLorean is defined, it means it's called from the browser, not
// the browserify.
if (typeof DeLorean !== 'undefined') {
for (var requirement in requirements) {
DeLorean.Flux.define(requirement, requirements[requirement]);
}
}
But when used in the browser with Require.js, DeLorean is undefined
because:
if (typeof define === 'function' && define.amd) {
define([], function () {
return DeLorean;
});
} else {
window.DeLorean = DeLorean;
}
When using delorean with require.js - the preferred way of using flight.js - via
var Flux = require('delorean').Flux
I get Uncaught TypeError: undefined is not a function
in delorean.js:105.
Thanks for help and thanks for the great job!
I am following the Tutorial and i am getting an Uncaught TypeError: Cannot read property 'listener' of undefined
I thought I typed something in wrong, so I copied and pasted all the code from the tutorial and it still didn't work. Here is my code.
In your example jsfiddle you access the stores directly {this.stores.increment.store.total}
Why not transfer the data automatically from the stores to the local state ?
The benefit will be, that it is unimportant for the view renderer from where the state data come (decoupled).
It would be nice if the scheme validation and calculation methods also worked for a collection of items as this is typically how Flux stores are arranged. If we discuss some syntax I can probably take this on... my thinking is another attribute on the stores isCollection: true for example.
In my view
import React from 'react';
import Header from './../header';
import {List} from './../listview';
import {Flux} from 'delorean';
var OverlaySearchView = React.createClass({
mixins: [Flux.mixins.storeListener],
watchStores: ['searchStore'],
handleFocus(){
console.log("focus");
this.setState({
searchViewActive: true
});
},
handleBlur(){
console.log("blur");
this.setState({
searchViewActive: false
});
},
addToCart(e, element){
cartActions.addToCart(element);
},
updateSearch(e){
var query = e.target.value;
if( query.length > 2 ){
// Never triggers
return this.trigger('search:query:' + this.props.searchType, query);
}
// Neither does this
this.trigger('search:clear');
},
render(){
var searchResults = '';
console.log('Current results', this.getStore('searchStore'), this.__dispatcher);
// Logs the current results and the dispatcher
var isActive = this.state.searchViewActive;
if( true && isActive === true ){
var medicines = this.getStore('searchStore');
searchResults = (
<div onClick={this.handleBlur}>
<div className="search-view-overlay">
</div>
<div className="search-results">
<List onClick={this.addToCart} elementRenderer={this.props.searchElementRenderer} source={medicines}></List>
</div>
</div>
);
}
return (
<div className={ "search-view" + (isActive?' active': '')}>
<Header>
<input className="search-bar form-control no-borders" placeholder="Search" type="text"
onFocus={this.handleFocus} onChange={this.updateSearch} />
</Header>
{searchResults}
</div>
);
}
});
export default OverlaySearchView;
The above component is nested inside a Router.State + Delorean.Flux.mixins.storeListener view from React-Router and delorean
Am i doing something wrong here ?
Due to react not deep cloning objects (facebook/react#2914) and the way that Delorean passes entire stores into state this makes the prevState parameter of componentWillUpdate useless. The prevState is always the current state.
thoughts?
Hey @darcyadams, I just started creating a file called FUTURE.md
. Can you inspect it and give your opinions?
Thanks! :)
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
The trace reported:
console.trace() events.js:148
EventEmitter.addListener events.js:148
EventEmitter.once events.js:174
(anonymous function) delorean.js:124
invokeResolver promise.js:41
Promise promise.js:28
__promiseGenerator delorean.js:123
(anonymous function) delorean.js:129
Dispatcher.waitFor delorean.js:133
Dispatcher.dispatch delorean.js:98
module.exports.Flux.createDispatcher.notify app-dispatcher.js:33
module.exports.notify notification-actions.js:6
React.createClass.notify index.js:51
boundMethod ReactCompositeComponent.js:1296
React.createClass.storeDidChange index.js:60
boundMethod ReactCompositeComponent.js:1296
(anonymous function) delorean.js:338
EventEmitter.emit events.js:99
module.exports.Flux.createStore.changeSettings settings-store.js:26
EventEmitter.emit events.js:77
Store.dispatchAction delorean.js:239
Dispatcher.dispatch delorean.js:102
module.exports.Flux.createDispatcher.changeSetting app-dispatcher.js:24
module.exports.changeSetting settings-actions.js:14
module.exports.React.createClass.onValueChange settings.js:13
boundMethod ReactCompositeComponent.js:1296
ReactCompositeComponent.createClass._handleChange ReactDOMInput.js:124
boundMethod ReactCompositeComponent.js:1296
executeDispatch EventPluginUtils.js:118
forEachEventDispatch EventPluginUtils.js:106
executeDispatchesInOrder EventPluginUtils.js:127
executeDispatchesAndRelease EventPluginHub.js:56
forEachAccumulated forEachAccumulated.js:30
EventPluginHub.processEventQueue EventPluginHub.js:270
runEventQueueInBatch ReactEventEmitterMixin.js:25
ReactEventEmitterMixin.handleTopLevel ReactEventEmitterMixin.js:51
handleTopLevelImpl ReactEventListener.js:87
Mixin.perform Transaction.js:142
ReactDefaultBatchingStrategy.batchedUpdates ReactDefaultBatchingStrategy.js:70
batchedUpdates ReactUpdates.js:114
ReactEventListener.dispatchEvent ReactEventListener.js:182
Our engineers keep getting caught out by this. You use getStore in the react mixin but forget to include the relevant store in the watchStores list.
We could prevent a lot of debugging pain by simply throwing an error in this instance ๐
I should build a Backbone.js plugin, so it don't have to be used just with React.
just wondering why you opted to use forceUpdate()
here instead of the more standard React pattern of setState
...
if (typeof store.store.getState === 'function') {
state = store.store.getState();
self.state.stores[storeName] = state;
self.forceUpdate();
}
does setState
only work on top level data? so you would have to set the .stores
property here in order to trigger an update? I was always under the impression that any call to setState
would trigger a render regardless of whether or not data actually changed.
Hey,
First of all, congrats for such great and simple to use/understand framework. Despite of being simple, I have a newbie question that might hide some lack of understanding of React.
In my React views, should I used 'onChange' as you show in [https://github.com/deloreanjs/delorean/blob/master/docs/tutorial.md] or 'storeDidChange' as in [https://github.com/deloreanjs/delorean/blob/master/docs/views.md#storedidchange-and-storesdidchange] ?
Thanks
So, I'm running this warn:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
I know that the origin is caused because in the ActionCreator
I'm requesting some data and resolving async:
LOAD: function(seeds){
request
.post(config.routes.data)
.type('form')
.send({
seeds: seeds
})
.end(function(err, res){
Dispatcher.dispatch(constants.LOAD, res);
});
}
If I comment the Dispatcher.dispatch
it works fine.
Since here all is clear, but if I shouldn't use this method I don't know what pattern should I follow to stop getting this warn, any idea?
as it says
JsFiddle example presented on the website does not work, see below:
var store = new Store();
console error: Object is not a function
There are no tests. (OMG)
The Ractive example did not work.
Here is my fix
http://jsfiddle.net/2r1k2k90/33/
dispatchers are not promised right now. it should be fixed.
There are possible mistakes in Readme file since It's not my native language.
http://jsfiddle.net/fkadev/40cx3146/
results in an error
componentWillUnmount: function () {
for (var storeName in this.stores) {
if (__hasOwn(this.stores, storeName)) {
var store = this.stores[storeName];
store.listener.removeAllListeners('change');
}
}
},
What if the store is listening by other components? It'll be crashed then right?
We need to find a better way I guess.
Hi,
I am trying to load DeLorean with require.js, but the EventEmitter and Promise attributes are missing from the DeLorean object.
I am loading it like this:
require.config({
paths: {
"delorean": "delorean.min"
}
});
require(['delorean'], function(DeLorean) {
console.log(DeLorean);
});
The console output then looks like this:
Object {Flux: Object, Dispatcher: function, Store: function}
Without require.js and loading DeLorean through basic script tag, the attributes are there.
Is there another step i missed to get this working?
Project domain expired : http://deloreanjs.com
@f the docs show creating new store instances like this: var myTodos = new TodoStore();
.
However, the Flux.createStore
method returns a function that returns a new store (ie a 'factory'). Using new
does not seem to cause issues (at least that I have found), but wouldn't the docs be more accurate with var myTodos = TodoStore(');
. Just wondering if there was a rational behind your decision to use use new
here.
DidChanged sounds kind of odd.
Maybe consider store(s)DidChange
to keep in line with React's lifecycle method componentDidUpdate
.
I noticed that if the store doesn't this.emit('change')
, then the dispatcher never resolves it's promise.
Dispatcher.dispatch('someAction', data).then(function() {
console.log('dispatch resolved!'); // only fires if we emit change
});
Is this intentional? The only reason I can think to architect it this way is to allow the Store to do some asynchronous work, which I thought is supposed to be the domain of the Action Creators?
I'd like a store to be allowed to mutate it's own data without emitting a change
event. Am I crazy?
BTW, I'm not using React so feel free to ridicule me ๐บ
Also, I'm very new to this Flux stuff so if I'm totally missing the point please do let me know.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.