@veams/component
Version:
Component Class for Components in Veams for static page apps
395 lines • 13.7 kB
JavaScript
'use strict';
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Represents a component constructor which supports
* options merging,
* binding and unbinding of events and subscriptions with template strings,
* rendering of templates
* and a destroy behaviour.
*
* @module @veams/component
* @author Sebastian Fitzner
*/
/**
* Imports
*/
var base_1 = require("@veams/base");
var get_string_value_1 = require("./helpers/get-string-value");
var template_engine_1 = require("./helpers/template-engine");
var event_handler_1 = require("./helpers/event-handler");
var DEFAULT_LIFECYCLES = {
create: true,
willMount: true,
didMount: true,
render: false
};
/**
* Custom Functions
*/
function buildEvtId(evtKeyArr, fnName) {
return evtKeyArr.join('_') + '_' + fnName;
}
/**
* Hidden variables
*/
// Custom event handler element which will be used in `events()` and `subscribe`
var eventElement = null;
var Component = /** @class */ (function (_super) {
__extends(Component, _super);
/**
* Constructor
*
* to save standard elements like el and options and
* execute initialize as default method.
*
* @param {Object} obj [{}] - Object which contains el, options from the DOM and namespace.
* @param {Object} options [{}] - Object which contains options of the extended class.
*/
function Component(obj, options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this, obj, options) || this;
_this.context = obj.context || window['Veams'];
_this.__eventElement = event_handler_1.default(_this.el);
if (!_this.context) {
console.info('@veams/component :: There is no context defined! When you want to use @veams/plugin-vent or any other singleton shared by your Veams instance provide the Veams object as context!');
}
_this.initialize(obj, options);
return _this;
}
Object.defineProperty(Component.prototype, "events", {
get: function () {
return this._events;
},
// ----------------------------------------------------------
// GETTER & SETTERS
// ----------------------------------------------------------
/**
* Get and set events object
*/
set: function (obj) {
this._events = obj;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Component.prototype, "subscribe", {
get: function () {
return this._subscribe;
},
/**
* Get and set subscribe object
*/
set: function (obj) {
this._subscribe = obj;
},
enumerable: true,
configurable: true
});
Component.prototype.addSubscriber = function (obj) {
if (!this.__subscribers) {
this.__subscribers = {};
}
this.__subscribers[obj.id] = {
delegate: obj.delegate,
type: obj.type,
event: obj.event,
handler: obj.handler
};
};
Object.defineProperty(Component.prototype, "_subscribers", {
get: function () {
return this.__subscribers;
},
enumerable: true,
configurable: true
});
// ----------------------------------------------------------
// STANDARD METHODS
// ----------------------------------------------------------
Component.prototype.initialize = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
};
/**
* Private method to create all necessary elements and bindings.
*
* @private
*/
Component.prototype.create = function () {
this.preRender();
this.registerEvents(this.events, false);
this.registerEvents(this.subscribe, true);
this.bindEvents();
};
/**
* Bind local and global events
*
* @public
*/
Component.prototype.bindEvents = function () {
};
/**
* Unbind events
*
* @public
*/
Component.prototype.unbindEvents = function () {
};
/**
* Pre-Render templates
* which can be used to render content into it
*
* @public
*/
Component.prototype.preRender = function () {
return this;
};
/**
* Render your module
*
* @public
*/
Component.prototype.render = function () {
return this;
};
/**
* Destroy component by unbinding events and
* removing element from DOM
*/
Component.prototype.destroy = function () {
this.unregisterEvents();
this.unbindEvents();
this.el.remove();
};
/**
* Render template with data
*
* @param {String} tplName - Template name which gets returned as rendered element.
* @param {Object} data - Data which gets handled by the template.
*/
Component.prototype.renderTemplate = function (tplName, data) {
if (!this.context.templater) {
console.error("\n\t\t\t\t@veams/component :: It seems that you haven't added the @veams/plugin-templater. In order to work with 'renderTemplate()' you need to add it!\n\t\t\t");
}
else {
return this.context.templater.render(tplName, data);
}
};
// ----------------------------------------------------------
// MOUNT PROCESS METHODS
// Mount process methods will be handled by the VeamsModules plugin
// ----------------------------------------------------------
/**
* This method will be executed after initialise
*/
Component.prototype.willMount = function () {
};
;
/**
* This method will be executed before unregistering events
*/
Component.prototype.willUnmount = function () {
};
;
/**
* This method will be executed after render
*/
Component.prototype.didMount = function () {
};
;
/**
* This method will be executed after unregistering events
*/
Component.prototype.didUnmount = function () {
};
;
// ----------------------------------------------------------
// EVENTS METHODS
// ----------------------------------------------------------
/**
* Register multiple events which are saved in an object.
*
* @param {Object} evts - Events object which contains an object with events as key and functions as value.
* @param {Boolean} global - Flag to switch between global and local events.
*
* @private
*/
Component.prototype.registerEvents = function (evts, global) {
var _this = this;
if (global === void 0) { global = false; }
if (evts) {
Object.keys(evts).forEach(function (key) {
_this.registerEvent(key, evts[key], global);
});
}
};
/**
* Register an event by using a simple template engine and
* a key/value pair.
*
* @param {String} evtKey - Event key which contains event and additionally a delegated element.
* @param {String} fn - Function defined as string which will be bound to this.
* @param {Boolean} global - Flag if global or local event .
*
* @public
*
* @example
* this.registerEvent('click .btn', 'render');
* this.registerEvent('click {{this.options.btn}}', 'render');
* this.registerEvent('{{App.EVENTS.custom.event', 'render');
* this.registerEvent('{{App.EVENTS.resize', 'render', true);
*/
Component.prototype.registerEvent = function (evtKey, fn, global) {
if (global === void 0) { global = false; }
if (typeof evtKey !== 'string') {
console.error('@veams/component :: Your event is not a string!');
return;
}
if (typeof fn !== 'string') {
console.error('@veams/component :: Your event handler function is not a string!');
return;
}
var evtKeyArr = evtKey.split(' ');
var arrlen = evtKeyArr.length;
var evtType = get_string_value_1.default.apply(this, [template_engine_1.default(evtKeyArr[0]), this.context]);
var bindFn = this[fn].bind(this);
var id = buildEvtId(evtKeyArr, fn);
if (arrlen > 2) {
throw new Error('@veams/component :: It seems like you have more than two strings in your events object!');
}
// Bind on this.el
if (arrlen === 1 && !global) {
this.__eventElement.on(evtType, bindFn);
this.addSubscriber({
type: 'event',
id: id,
event: evtType,
handler: bindFn
});
}
else if (arrlen === 1 && global) {
if (!this.context && !this.context.Vent) {
console.warn('@veams/component :: There is no context or the Vent object is missing. Subscribing to global events will not work without it!');
return;
}
this.context.Vent.subscribe(evtType, bindFn);
this.addSubscriber({
type: 'globalEvent',
id: id,
event: evtType,
handler: bindFn
});
}
else {
var delegate = get_string_value_1.default.apply(this, [template_engine_1.default(evtKeyArr[1])]);
this.__eventElement.on(evtType, delegate, bindFn);
this.addSubscriber({
type: 'delegatedEvent',
delegate: delegate,
id: id,
event: evtType,
handler: bindFn
});
}
};
/**
* Delete all registered events.
*/
Component.prototype.unregisterEvents = function () {
for (var key in this._subscribers) {
if (this._subscribers.hasOwnProperty(key)) {
var obj = this._subscribers[key];
if (obj.type === 'globalEvent') {
if (!this.context && !this.context.Vent) {
console.warn('@veams/component :: There is no context or the Vent object is missing. Subscribing to global events will not work without it!');
return;
}
this.context.Vent.unsubscribe(obj.event, obj.handler);
}
else if (obj.type === 'delegatedEvent') {
this.__eventElement.off(obj.event, obj.delegate, obj.handler);
}
else {
this.__eventElement.off(obj.event, obj.handler);
}
}
}
};
/**
* Unregister an event by using the saved subscribers and
* a key/value pair.
*
* @param {String} evtKey - Event key which contains event and additionally a delegated element.
* @param {String} fn - Function defined as string which will be unbound to this.
*
* @public
*
* @example
* this.unregisterEvent('click .btn', 'render');
* this.unregisterEvent('click {{this.options.btn}}', 'render');
* this.unregisterEvent('{{App.EVENTS.custom.event', 'render');
* this.unregisterEvent('{{App.EVENTS.resize', 'render');
*/
Component.prototype.unregisterEvent = function (evtKey, fn) {
var evtKeyArr = evtKey.split(' ');
var id = buildEvtId(evtKeyArr, fn);
if (this._subscribers[id]) {
var obj = this._subscribers[id];
if (obj.type === 'globalEvent') {
if (!this.context && !this.context.Vent) {
console.warn('@veams/component :: There is no context or the Vent object is missing. Subscribing to global events will not work without it!');
return;
}
this.context.Vent.unsubscribe(obj.event, obj.handler);
}
else if (obj.type === 'delegatedEvent') {
this.__eventElement.off(obj.event, obj.delegate, obj.handler);
}
else {
this.__eventElement.off(obj.event, obj.handler);
}
}
};
return Component;
}(base_1.default));
function autocreate(lifecycles) {
var mergedLifeCycles = __assign({}, DEFAULT_LIFECYCLES, lifecycles);
return function creatInstance(instance) {
if (mergedLifeCycles.create) {
instance.create();
}
if (mergedLifeCycles.willMount) {
instance.willMount();
}
if (mergedLifeCycles.didMount) {
instance.didMount();
}
if (mergedLifeCycles.render) {
instance.render();
}
return instance;
};
}
exports.autocreate = autocreate;
exports.default = Component;
//# sourceMappingURL=index.js.map