Skip to content

Instantly share code, notes, and snippets.

@sakamies
Last active April 5, 2017 19:44
Show Gist options
  • Save sakamies/576749dd68d1ec635f65b72d3ae73939 to your computer and use it in GitHub Desktop.
Save sakamies/576749dd68d1ec635f65b72d3ae73939 to your computer and use it in GitHub Desktop.
Kinda sorta my accidental JS framework
Model = require('./model.js')
SomeModule = require('./somemodule.js')
const model = new Model()
const moduleOne = new SomeModule(document.querySelector('#stuff'), model)
const moduleDuo = new SomeModule(document.querySelector('#other-stuff'), model)
//Kick off the app by setting some initial data
model.set(initialData)
'use strict'
module.exports = Model;
// modelInstance.get(key) returns value
// modelInstance.set(key, value) modifies data, signals update
// modelInstance.set({key: value, key2: value2}) modifies multiple keys in data, signals value for each key separately
// modelInstance.signal(key, value), does not modify data, signals value
// modelInstance.listen(key, function) listen to a signal
// modelInstance.listen(key, key, key, function) listen to many signals with one function
function Model (modelData) {
let listeners = {}
return {has, get, set, keys, listen, signal, ignore}
function keys() {
return Object.keys(modelData);
}
function dump() {
//Returns a copy of all current data
return Object.assign({}, modelData);
}
function has(key) {
if (key in modelData) {
return true;
} else {
return false;
}
}
function get (key) {
//If no key is given, return a copy of all data
if (key === undefined) {
return Object.assign({}, modelData);
} else if (key in modelData) {
return modelData[key];
} else {
return undefined;
}
}
//model.set takes (key, value) or ({key: value, key: value}) for multiple key value pairs
function set (...args) {
let setData = {};
//If first param is an object, update all matching keys in model
if (args[0] === Object(args[0])) {
setData = args[0];
} else {
let key = args[0];
let value = args[1];
setData[key] = value;
}
//Update props in model & send signals for changes. Only update existing props, don't add new ones.
for (let key in setData) {
if (key in modelData) {
let value = setData[key];
modelData[key] = value;
signal(key, value);
}
}
}
//Listen takes any number of keys to listen to, and a listener as the last argument
function listen (...args) {
let listener = args.pop();
let keys = args;
for (let key of keys) {
if (key in listeners === false) {
//Each key has an array of listeners, let's add the array if it's doesn't exist
listeners[key] = []
}
listeners[key].push(listener)
}
}
function signal (key, value) {
if (key in listeners) {
listeners[key].forEach((listener)=>{
listener(key, value)
})
}
}
function ignore (key, listener) {
if (key in listeners) {
listeners[key] = listeners[key].filter((item) => {
return item !== listener
})
}
}
}
'use strict';
module.exports = SomeModule;
function SomeModule (element, model) {
let maybeSomeInternalState;
init();
//Reveal any public props or methods
return {node: element}
function init() {
maybeSomeInternalState = 0
//Bind dom events this module is interested in
containerElement.addEventListener('input', input);
//Listen to model changes, perhaps dispatched by some other module
model.listen('some_key', update);
}
function input (event) {
let target = event.target;
let key = target.name;
let value = target.value;
//A dom event triggers a model change, filter in/out relevant keys
model.set(key, value)
}
function update (key, value) {
maybeSomeInternalState = value
//Render any relevant dom changes here
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment