mirror of
https://github.com/0x1d/esp8266-laser.git
synced 2025-12-17 02:46:39 +01:00
ui
This commit is contained in:
62
frontend/scripts/core/App.js
Normal file
62
frontend/scripts/core/App.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
import * as Components from '../components/exports';
|
||||
|
||||
|
||||
export default class App {
|
||||
|
||||
constructor() {
|
||||
this.dataStores = [];
|
||||
}
|
||||
|
||||
withDataStore(dataStore) {
|
||||
this.dataStores[dataStore.constructor.name] = dataStore;
|
||||
return this;
|
||||
}
|
||||
|
||||
getStore(dataStore) {
|
||||
return this.dataStores[dataStore];
|
||||
}
|
||||
|
||||
run(ctx) {
|
||||
this._loadComponents(ctx);
|
||||
this._beforeInitComponents();
|
||||
this._initComponents();
|
||||
return this;
|
||||
}
|
||||
|
||||
_loadComponents(ctx) {
|
||||
this.components = this.components || [];
|
||||
for (let c in Components) {
|
||||
let nodes = ctx ? ctx.find('.' + c) : [];
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let component = new Components[c](this, $(nodes[i]));
|
||||
this.components.push(component);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
_initComponents() {
|
||||
this.components.forEach(this._initComponent);
|
||||
}
|
||||
|
||||
_beforeInitComponents() {
|
||||
this.components.forEach(this._beforeInitComponent);
|
||||
}
|
||||
|
||||
_initComponent(component) {
|
||||
component.init();
|
||||
}
|
||||
|
||||
_beforeInitComponent(component) {
|
||||
component.beforeInit();
|
||||
}
|
||||
|
||||
render() {
|
||||
for (let component in this.components) {
|
||||
this.components[component].render();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
45
frontend/scripts/core/Component.js
Normal file
45
frontend/scripts/core/Component.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import Mustache from 'mustache';
|
||||
import $ from 'jquery';
|
||||
import DataField from './data/DataField';
|
||||
|
||||
export default class Component {
|
||||
|
||||
constructor(ctx, node, withTemplate = true) {
|
||||
this.ctx = ctx;
|
||||
this.node = node;
|
||||
this.component = this.constructor.name;
|
||||
this.template = withTemplate ? $.get(this.component + '.html') : undefined; //document.querySelector('#' + this.component).import.body.textContent;
|
||||
this.data = {};
|
||||
//console.log('init ' + this.component);
|
||||
}
|
||||
|
||||
beforeInit() {
|
||||
this.subscribe();
|
||||
}
|
||||
|
||||
init() {}
|
||||
subscribe() {}
|
||||
templateHelpers() { return {}; }
|
||||
|
||||
bindData() {
|
||||
let _this = this;
|
||||
this.node.find('[data-bind]').each(function() {
|
||||
var field = $(this);
|
||||
_this.data[field.data('bind')] = new DataField(field);
|
||||
});
|
||||
}
|
||||
|
||||
render(data) {
|
||||
if (data) data.helpers = this.templateHelpers();
|
||||
return this.template
|
||||
.then((template) => {
|
||||
return new Promise((fulfill, reject) => {
|
||||
this.node.html(Mustache.render(template, data));
|
||||
this.bindData();
|
||||
//this.ctx._loadComponents(this.node);
|
||||
fulfill();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
20
frontend/scripts/core/Mediator.js
Normal file
20
frontend/scripts/core/Mediator.js
Normal file
@@ -0,0 +1,20 @@
|
||||
export default class Mediator {
|
||||
|
||||
constructor() {
|
||||
this.events = [];
|
||||
}
|
||||
|
||||
on(event, callback, context){
|
||||
this.events[event] = this.events[event] || [];
|
||||
this.events[event].push(context ? callback.bind(context) : callback);
|
||||
};
|
||||
|
||||
trigger(event, args){
|
||||
if(this.events[event]){
|
||||
for (var i = this.events[event].length - 1; i >= 0; i--) {
|
||||
this.events[event][i](args || {});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
28
frontend/scripts/core/data/DataBinding.js
Normal file
28
frontend/scripts/core/data/DataBinding.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
export default class DataBinding {
|
||||
|
||||
inputChange(node, model = {}) {
|
||||
node.on('keyup', function() {
|
||||
model.value = this.value;
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
inputHandler() {
|
||||
return {
|
||||
set: function(target, prop, newValue) {
|
||||
if (prop == 'value' && target.id) {
|
||||
target[prop] = newValue;
|
||||
$('[data-bind="' + target.id + '"]').val(newValue);
|
||||
return true;
|
||||
} else return false;
|
||||
|
||||
},
|
||||
get: function(target, name) {
|
||||
return target[name];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
23
frontend/scripts/core/data/DataField.js
Normal file
23
frontend/scripts/core/data/DataField.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import DataBinding from './DataBinding';
|
||||
|
||||
export default class DataField {
|
||||
|
||||
constructor(node, data) {
|
||||
this.node = node;
|
||||
this.data = {
|
||||
id: this.node.data('bind')
|
||||
};
|
||||
this.bind();
|
||||
}
|
||||
bind() {
|
||||
this.dataBinding = new DataBinding();
|
||||
this.dataBinding.inputChange(this.node, this.data);
|
||||
this.proxy = new Proxy(this.data, this.dataBinding.inputHandler());
|
||||
}
|
||||
get value() {
|
||||
return this.proxy.value;
|
||||
}
|
||||
set value(newValue) {
|
||||
this.proxy.value = newValue;
|
||||
}
|
||||
}
|
||||
9
frontend/scripts/core/store/DataStore.js
Normal file
9
frontend/scripts/core/store/DataStore.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export default class DataStore {
|
||||
constructor(mediator){
|
||||
this.mediator = mediator;
|
||||
}
|
||||
load(entry){}
|
||||
save(entry){}
|
||||
add(entry){}
|
||||
delete(entry){}
|
||||
}
|
||||
37
frontend/scripts/core/store/RestStore.js
Normal file
37
frontend/scripts/core/store/RestStore.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import $ from 'jquery';
|
||||
import Mediator from '../Mediator';
|
||||
import DataStore from './DataStore';
|
||||
import StoreAction from './StoreAction';
|
||||
|
||||
export default class RestStore extends DataStore {
|
||||
constructor(endpoint, mediator = new Mediator()){
|
||||
super(mediator);
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
load(entry){
|
||||
return this.request(StoreAction.LOAD, 'GET', entry);
|
||||
}
|
||||
save(entry){
|
||||
return this.request(StoreAction.SAVE, 'POST', entry);
|
||||
}
|
||||
add(entry){
|
||||
return this.request(StoreAction.ADD, 'PUT', entry);
|
||||
}
|
||||
delete(entry){
|
||||
return this.request(StoreAction.DELETE, 'POST', entry);
|
||||
}
|
||||
request(event, type, payload){
|
||||
return $.ajax({
|
||||
url: this.endpoint,
|
||||
type: type,
|
||||
data: payload
|
||||
})
|
||||
.then(JSON.parse)
|
||||
.then((response) => {
|
||||
this.mediator.trigger(event, response);
|
||||
});
|
||||
}
|
||||
on(event, subscriber, context){
|
||||
this.mediator.on(event, subscriber, context);
|
||||
}
|
||||
}
|
||||
6
frontend/scripts/core/store/StoreAction.js
Normal file
6
frontend/scripts/core/store/StoreAction.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
LOAD: 'load',
|
||||
SAVE: 'save',
|
||||
ADD: 'add',
|
||||
DELETE: 'delete'
|
||||
}
|
||||
Reference in New Issue
Block a user