The website: matreshka.ioExamples: github/matreshkajs/examples-and-tutorialsOn Github: github/matreshkajs/matreshka
Just to remind: Matreshka.js is an alternative JavaScript framework for single page apps.
bindNode function binds a property of an object to HTML node.
const object = { name: 'Brendan' };const node = document.querySelector('.name'); Matreshka.bindNode(object, 'name', node);object.name = 'Doug';
A property change also changes bound node and vice versa (e. g. if a user types something). Matreshka.js handles all HTML form elements out of the box. Custom element binding is described at the documentation.
calc function makes one property to be dependent from others.
Matreshka.calc(object, 'fullName**'**, ['firstName', 'lastName'], (firstName, lastName) => {return `${firstName} ${lastName}`});
object.firstName = 'Brendan';object.lastName = 'Eich';_// …_console.log(object.fullName); // “Brendan Eich”
When a source property is changed (firstName or lastName) then the target property (fullName) is recalculated.
calc and bindNode makes possible to define long chains of dependencies: a property a is dependent on an element e1, a property b is dependent on the property a, a property c is dependent on elements e2 and e3 and also on property b. As the result a change of the property b also changes e1, e2, e3 and so on…
You can imagine such dependencies as a an Excell table. Every moment of time you think about one formula but not about multitudinous dependencies of all cells. As the result, you get less bugs because it’s not obligatory to keep all the “table” (application) logic in you mind. At the documentation you’ll find more information about calc.
on function listens for events and trigger function fires them.
Matreshka.on(object, 'something', () => {alert('something is happened')});
Matreshka.trigger(object, 'something');
on function can listen for property change event to execute custom code. In this way you can add another thing to the dependencies chain (for example fetch request).
const { on } = Matreshka;
on(object, 'change:fullName', async () => {await fetch('/api/name', { method: 'post', body: this.fullName });// …});
Events at Matreshka.js is wide and interesting topic. With them it’s possible to listen for delegated events of an object (e. g. listen for changes deep inside object tree), DOM events, delegated DOM events etc. You can read about them at “The events” article.
mediate function adds runtime validation and conversion of a property values. For example, you can define a property of definite type, you can limit the property to a specified range, you can throw an exception if needed.
Matreshka.mediate(object, 'x', x => String(x));object.x = 42;console.log(object.x, typeof object.x); // “42”, “string”
Matreshka class instances have the same set of methods with one difference: this is used instead of an object argument.
class User extends Matreshka {constructor() {super();this.bindNode('fullName', '.full-name');this.calc('fullName', ['firstName', 'lastName'],(firstName, lastName) => `${firstName} ${lastName}`);// also chained call can be used there:// super().bindNode(...).calc(...); }}
This class unites classes Matreshka.Object and Matreshka.Array described below making them to have a common method set.
Class Matreshka.Object is responsible for key-value type of data. In Matreshka.js terms “data” means properties that a developer might want to send to a server or store at local DB. Thus, the framework need to know which properties are responsible for data (e. g. user name) and which are responsible for temporary application state (e. g. is DOM element hidden or not). Such properties are defined by addDataKeys method.
class User extends Matreshka.Object {constructor() {super();this.firstName = 'Brendan';this.lastName = 'Eich';this.language = 'JavaScript';this.addDataKeys(['firstName', 'lastName']);
_// '{“firstName”: “Brendan”, “lastName”: “Eich”}'_
console.log(**JSON**.stringify(**this**));
}}
More detailed about the Matreshka.Object class you can read there.
Matreshka.Array is responsible for array-like collections at the framework. In addition to the methods inherited from Matreshka, instances of Matreshka.Array include all the methods from native Array (push, splice, map, reduce…).
Similar to Backbone.Collection, you can define a “model” (Model property). The difference is that it can be any JavaScript class.
class Users extends Matreshka.Array {get Model() { return User; }constructor() {super();this.push({ firstName: 'Brendan', lastName: 'Eich' });console.log(this[0] instanceof User); // true }}
A collection can be automatically rendered when its items are changed. To do this, you need to set where to insert newly created DOM elements and how to render them. To set a place where the elements should be rendered you need to bind the container element to sandbox or container property (the difference is described at the documentation). To declare how to render DOM elements you should define virtual method itemRenderer (or renderer for Model class).
class Foo extends Matreshka.Array {itemRenderer(){return '<div>Hello, world!</div>'}
constructor() {super();this.bindNode('sandbox', '.sandbox-node');// inserts <div>Hello, world!</div> to .sandbox-nodethis.push({});}}
You can read there more detailed about the Matreshka.Array class.
All functions and classes can be imported as CJS/ES2015 module.
import calc from 'matreshka/calc';import MatreshkaArray from 'matreshka/array';
A library called matreshka-router is responsible for the routing. It binds properties to parts of a page address.
Matreshka.initRouter(object, ‘/a/b/c/’);object.a = 'foo';object.b = 'bar';object.c = 'baz'; // makes location.hash to be #!/foo/bar/baz/
Matreshka.js fills the gap between a junior and a senior and allows to write modular and extensible applications at the beginning of web developer’s career. Everything you need to know to get started is JavaScript.