Skip to content

Commit 1fb7c6f

Browse files
committed
All the mixins
0 parents  commit 1fb7c6f

8 files changed

+345
-0
lines changed

Diff for: AltManagerMixin.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
'use strict'
2+
/**
3+
* This mixin lets you setup your listeners for a single store/action for
4+
* that uses AltManager.js, it will re-attach listeners when the props.alt
5+
* changes. It requires an alt instance as props.alt to be passed. For exmaple:
6+
*
7+
* <FooComponent alt={manager.get('MyAltInstName')} />
8+
*
9+
* Your component will have access to this.action and this.store which contains
10+
* the dyanmically available Alt action instance and Alt store instance.
11+
*
12+
* Usage:
13+
*
14+
* mixins: [AltManagerMixin],
15+
*
16+
* statics: {
17+
* registerStore: FooStore,
18+
* registerAction: FooAction,
19+
* },
20+
*
21+
*
22+
* onNewAlt(newState, newProps) {
23+
* // Do whatever you want here. This is an optional callback you can have
24+
* // inside your component if it needs to handle certain actions if a new
25+
* // Alt instance was created.
26+
* }
27+
*
28+
*/
29+
var AltManagerMixin = {
30+
31+
action: null,
32+
store: null,
33+
34+
componentWillMount: function() {
35+
// we need to init the store and actions during creation
36+
this.initProps(this.props)
37+
},
38+
39+
componentWillReceiveProps: function(newProps) {
40+
// unlisten from old alt store if change of alt
41+
if (this.props.alt !== newProps.alt) {
42+
this.store.unlisten(this.listenState)
43+
// init the new props
44+
this.initProps(newProps)
45+
} else {
46+
// we always need to set the new state if the props changed
47+
this.setState(this.store.getState())
48+
}
49+
},
50+
51+
listenState: function(data) {
52+
// we make this a method here so we can pass it to unlisten
53+
this.setState(data)
54+
},
55+
56+
initProps: function(props) {
57+
var Store = this.constructor.registerStore
58+
var Action = this.constructor.registerAction
59+
if (!Store) {
60+
throw new ReferenceError('registerStore has not been defined')
61+
}
62+
63+
if (!Action) {
64+
throw new ReferenceError('registerAction has not been is defined')
65+
}
66+
67+
var storeName = Store.name
68+
var actionName = Action.name
69+
70+
this.action = props.alt.getActions(actionName)
71+
this.store = props.alt.getStore(storeName)
72+
73+
if (!this.action) {
74+
props.alt.addActions(actionName, Action)
75+
this.action = props.alt.getActions(actionName)
76+
this.store = props.alt.createStore(Store, null, props.alt)
77+
if (this.onNewAlt) {
78+
this.onNewAlt(this.store.getState(), props)
79+
}
80+
}
81+
82+
this.setState(this.store.getState())
83+
this.store.listen(this.listenState)
84+
},
85+
86+
componentWillUnmount: function() {
87+
this.store.unlisten(this.listenState)
88+
}
89+
}
90+
91+
module.exports = AltManagerMixin

Diff for: FluxyMixin.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
'use strict'
2+
/**
3+
* This mixin lets you setup your listeners. It is similar to Fluxible's mixin.
4+
*
5+
* Usage:
6+
*
7+
* mixins: [FluxyMixin],
8+
*
9+
* statics: {
10+
* storeListeners: {
11+
* doFoo: FooStore,
12+
* doBar: BarStore
13+
* }
14+
* },
15+
*
16+
* doFoo: function (storeState) {
17+
* this.setState({ foo: FooStore.getState() })
18+
* },
19+
*
20+
* doBar: function (storeState) { },
21+
*
22+
* render: function () {
23+
* // state will be in the keys you provided
24+
* this.state.foo
25+
* }
26+
*
27+
* ----
28+
*
29+
* You can also pass in an Array of stores to storeListeners:
30+
*
31+
* statics: {
32+
* storeListeners: [FooStore, BarStore]
33+
* }
34+
*
35+
* Changes will then be passed to a function `onChange` which you will have
36+
* to define:
37+
*
38+
* onChange() {
39+
* this.setState({
40+
* foo: FooStore.getState(),
41+
* bar: BarStore.getState()
42+
* })
43+
* }
44+
*/
45+
var Subscribe = require('./Subscribe')
46+
47+
var FluxyMixin = {
48+
componentDidMount: function () {
49+
Subscribe.create(this)
50+
51+
var stores = this.constructor.storeListeners
52+
53+
if (Array.isArray(stores)) {
54+
if (!this.onChange) {
55+
throw new ReferenceError(
56+
'onChange should exist in your React component but is not defined'
57+
)
58+
}
59+
60+
stores.forEach(function (store) {
61+
Subscribe.add(this, store, this.onChange)
62+
}, this)
63+
} else {
64+
Object.keys(stores).forEach(function (handler) {
65+
if (!this[handler]) {
66+
throw new ReferenceError(
67+
handler + ' does not exist in your React component'
68+
)
69+
}
70+
71+
Subscribe.add(this, stores[handler], this[handler])
72+
}, this)
73+
}
74+
},
75+
76+
componentWillUnmount: function () {
77+
Subscribe.destroy(this)
78+
}
79+
}
80+
81+
module.exports = FluxyMixin

Diff for: IsomorphicMixin.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict'
2+
module.exports = { create: createIsomorphicMixin }
3+
4+
function createIsomorphicMixin(alt) {
5+
return {
6+
componentWillMount: function () {
7+
if (!this.props.altStores) {
8+
throw new ReferenceError(
9+
'altStores was not provided as a property to the react element'
10+
)
11+
}
12+
alt.bootstrap(JSON.stringify(this.props.altStores))
13+
}
14+
}
15+
}

Diff for: ListenerMixin.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict'
2+
var Subscribe = require('./Subscribe')
3+
4+
var ListenerMixin = {
5+
componentWillMount: function () {
6+
Subscribe.create(this)
7+
},
8+
9+
componentWillUnmount: function () {
10+
Subscribe.destroy(this)
11+
},
12+
13+
listenTo: function (store, handler) {
14+
Subscribe.add(this, store, handler)
15+
},
16+
17+
listenToMany: function (stores, handler) {
18+
stores.forEach(function (store) {
19+
this.listenTo(store, handler)
20+
}, this)
21+
},
22+
23+
getListeners: function () {
24+
return Subscribe.listeners(this)
25+
}
26+
}
27+
28+
module.exports = ListenerMixin

Diff for: ReactStateMagicMixin.js

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
'use strict'
2+
/**
3+
* This mixin automatically sets the state for you based on the key you provide
4+
*
5+
* Usage:
6+
*
7+
* mixins: [ReactStateMagicMixin],
8+
*
9+
* statics: {
10+
* registerStores: {
11+
* foo: FooStore,
12+
* bar: BarStore
13+
* }
14+
* },
15+
*
16+
* render: function () {
17+
* // state will be in the keys you provided
18+
* this.state.foo
19+
* this.state.bar
20+
* }
21+
*
22+
* Alternatively:
23+
*
24+
* statics: {
25+
* registerStore: FooStore
26+
* },
27+
*
28+
* render: function () {
29+
* // all of FooStore's state will be dumped into this.state
30+
* this.state
31+
* }
32+
*/
33+
var Subscribe = require('./Subscribe')
34+
35+
var ReactStateMagicMixin = {
36+
getInitialState: function () {
37+
return this.getStateFromStores()
38+
},
39+
40+
componentDidMount: function () {
41+
Subscribe.create(this)
42+
43+
var stores = this.constructor.registerStores
44+
45+
if (this.constructor.registerStore && this.constructor.registerStores) {
46+
throw new ReferenceError(
47+
'You are attempting to use `registerStore` and `registerStores` ' +
48+
'pick one'
49+
)
50+
}
51+
52+
if (this.constructor.registerStore) {
53+
Subscribe.add(this, this.constructor.registerStore, this.altSetState)
54+
} else {
55+
Object.keys(stores).forEach(function (formatter) {
56+
Subscribe.add(this, stores[formatter], this.altSetState)
57+
}, this)
58+
}
59+
},
60+
61+
componentWillUnmount: function () {
62+
Subscribe.destroy(this)
63+
},
64+
65+
getStateFromStores: function () {
66+
if (this.constructor.registerStore) {
67+
return this.constructor.registerStore.getState()
68+
}
69+
70+
var stores = this.constructor.registerStores
71+
72+
return Object.keys(stores).reduce(function (obj, key) {
73+
return obj[key] = stores[key].getState(), obj
74+
}, {})
75+
},
76+
77+
altSetState: function () {
78+
this.setState(this.getStateFromStores())
79+
}
80+
}
81+
82+
module.exports = ReactStateMagicMixin

Diff for: Subscribe.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict'
2+
3+
var Subscribe = {
4+
create: function (context) {
5+
context._AltMixinRegistry = context._AltMixinRegistry || []
6+
},
7+
8+
add: function (context, store, handler) {
9+
context._AltMixinRegistry.push(store.listen(handler))
10+
},
11+
12+
destroy: function (context) {
13+
context._AltMixinRegistry.forEach(function (f) { f() })
14+
context._AltMixinRegistry = []
15+
},
16+
17+
listeners: function (context) {
18+
return context._AltMixinRegistry
19+
}
20+
}
21+
22+
module.exports = Subscribe

Diff for: index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = new Error('Require each individual mixin')

Diff for: package.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "alt-mixins",
3+
"version": "1.0.0",
4+
"description": "Mixins for use with Alt and react",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "[email protected]:altjs/mixins.git"
12+
},
13+
"keywords": [
14+
"mixins",
15+
"react",
16+
"alt",
17+
"flux"
18+
],
19+
"author": "Josh Perez <[email protected]>",
20+
"license": "MIT",
21+
"bugs": {
22+
"url": "https://github.com/altjs/mixins/issues"
23+
},
24+
"homepage": "https://github.com/altjs/mixins"
25+
}

0 commit comments

Comments
 (0)