<select class="my-select"> <option>1</option> <option>2</option> <option>3</option> </select>  var mk = new Matreshka(); .my-select element: mk.bindElement( 'x', '.my-select' );  mk.x = 2;  mk.on( 'change:x', function( evt ) { alert( 'x   ' + evt.value ); }); "x " : mk.x = '';  requirejs.config({ paths: { xclass: 'path/to/matreshka', matreshka: 'path/to/matreshka' } }); require(['xclass', 'matreshka'], function(Class, MK) { return Class({ 'extends': MK //... }); });  require(['path/to/matreshka'], function( MK ) { return MK.Class({ 'extends': MK // ... }); }); Class property that duplicates the function that creates classes: there is no need to request an additional module.addDependence method was renamed to addDependency at the prompt of the buriy habrauser (thanks to him), the old method is marked as “outdated”.[ , "", , "", , "" ... ] is an array, with odd elements — instances of classes, even-numbered keys of these instances, on which the desired property depends. Take a look at an example: this.addDependency( 'a', [ anotherInstance1, 'b', this, 'c', anotherInstance2, 'd' ], function( b, c, d ) { return b + c + d; }); "a" depends on the property "b" object anotherInstance1 , on the property "d" object anotherInstance2 and on its own property "c" . The old syntax still works: this.addDependency( 'a', 'b c', function( b, c ) { return b + c; }); addDependency used addDependency . Imagine a situation where property "a" depends on property "b" , property "b" depends on property "c" , and property "c" , in turn, depends on "a" . Abstract illustration for example: this.addDependency( 'a', 'b', function( b ) { return b * 2; }); this.addDependency( 'b', 'c', function( c ) { return c * 3; }); this.addDependency( 'c', 'a', function( a ) { return a / 5; }); addDependency in a new form allows you to build mutual dependencies based on complex (or not) formulas, without fear of errors in the implementation of these formulas. An example of calculating the perimeter of a rectangle by the length of the sides, and calculating the lengths of the sides: this.addDependency( 'p', 'a b', function( a, b ){ return (a + b) * 2; }); this.addDependency( 'a', 'p b', function( p, b ){ return p/2 - b; }); this.addDependency( 'b', 'p a', function( p, a ){ return p/2 - a; });  var doSomethingHeavy = function( i ) { console.log( 'Ok', i ); }; var procrastinateSomethingHeavy = MK.procrastinate( doSomethingHeavy ); for( var i = 0; i < 100; i++ ) { procrastinateSomethingHeavy( i ); } // >> Ok 100  var procrastinate = function ( f, d, thisArg ) { var timeout; if( typeof d !== 'number' ) { thisArg = d; d = 0; } return function() { var args = arguments, _this = this; clearTimeout( timeout ); timeout = setTimeout( function() { f.apply( thisArg || _this, args ); }, d || 0 ); }; };  var procrastinateSomethingHeavy = MK.procrastinate( function() { console.log( 'Ok' ); }, 1000 ); setInterval( function() { procrastinateSomethingHeavy(); }, 500 ); //    initializeon (for which DOM event the property is updated), getValue (how to extract the property value from the element), setValue (how to set the property value for the element). More details here (by the way, all the articles about Matryoshka are updated every release and are relevant material). Now there is one more optional property initialize .initialize is a function that starts at the time of binding, or rather, before it. The task of the function is to sweeten the code. Take a look at an example from the first article :First, before binding, we will announce the slider:<div class="slider"></div>$( ".slider" ).slider({ min: 0, max: 100 });
Secondly, we declare a copy of the Matryoshka:var mk = new Matreshka();
Next, call the binding:mk.bindElement( 'x', '.slider', { on: 'slide', // , getValue: function() { return $( this ).slider( 'option', 'value' ); // (. jQuery ui.slider)? }, setValue: function( v ) { $( this ).slider( 'option', 'value', v ); // (. jQuery ui.slider)? } });
slider class (first, applying the plugin, then tying the element). Now this can be avoided: var mk = new Matreshka(); mk.bindElement( 'x', '.slider', { initialize: function() { $( this ).slider({ min: 0, max: 100 }); }, on: 'slide', getValue: function() { return $( this ).slider( 'option', 'value' ); }, setValue: function( v ) { $( this ).slider( 'option', 'value', v ); } });  this.defineSetter( 'x', function( value ) { return alert( value ); });  this.x = 1; this.on( 'change:x', function( evt ) { // ,    -   alert( 'x is changed to ' + evt.value ); }); this.defineSetter( 'x', function() { // ... }); this.x = 2; "@_" var mk = new MK; mk.on( 'x@yeah', function() { alert( 'yeah' ); }); mk.x = new MK; mk.x.trigger( 'yeah' ); "@_" for MK.ObjectMK.Object (see the article about MK.Object for the JSON key or the key responsible for the data). var mkObject = new MK.Object; mkObject.on( '@yeah', function() { alert( 'yeah' ); }); mkObject.jset( 'x', new MK ); mkObject.x.trigger( 'yeah' ); "@_" for MK.ArrayMK.Object , MK.Object the same opportunity: the handler is hung on any of the array elements, provided that this element is inherited from the Matryoshka. var mkArray = new MK.Array; mkArray.on( '@yeah', function() { alert( 'yeah' ); }); mkArray.push( new MK ); mkArray[ 0 ].trigger( 'yeah' ); "yeah" event, you can safely listen to other events, for example, "change:" this.on( 'x@change:y', function() { /* ... */ } ); this.on( '@change:y', function() { /* ... */ } );  { a: [{ b: { c: { e: 1 } } }, { b: { d: { e: 2 } } }] } "e" property, you can add this handler: this.on( 'a@@b@@change:e', function() { /* ... */ } ); null and Matreshka # boundAll , which returns a collection of bound elements. There may be problems for newbies who work with jQuery and are not familiar with VanillaJS in understanding the term “collection” and are used to knowing the dollar. Therefore, the $bound method was added to the framework, which does the exact same thing as Matreshka # boundAll . this.bindElement( 'a', '#x, #y' ); this.$bound( 'a' ).animate( /* ... */ ); //   jQuery  usejQuery and useBalalaikausejQuery methods (in case jQuery was connected after Matryoshka) and useBalalaika (in case jQuery was connected before Matrioshka , but you still want to use the built-in library). Now there was a method that allows using any jQuery-like library in general ( usejQuery and useBalalaika are marked as obsolete). MK.useAs$( jQuery ); MK.useAs$( jQuery.noConflict() ); MK.useAs$( Zepto ); MK.useAs$( MK.$b ); //   var MyClass = Class({ 'extends': AnotherClass, constructor: function() { AnotherClass.call( this, arguments ); }, someNewMethod: function() { /* ... */ } });  var MyClass = Class({ 'extends': AnotherClass, constructor: AnotherClass.same(), someNewMethod: function() { /* ... */ } }); "click::x" ) before the element has been bound this.bindElement( 'x', '.my-element' ); this.on( 'click::x', function() { alert( '.my-element is clicked' ); }); bind event and adding a handler upon the occurrence of this event: this.on( 'bind:x', function() { this.on( 'click::x', function() { alert( '.my-element is clicked' ); }); }); this.bindElement( 'x', '.my-element' );  this.on( 'click::x', function() { alert( '.my-element is clicked' ); }); this.bindElement( 'x', '.my-element' ); thisundefined as an argument"modify" event is triggered for the Matreshka.Array class"delete" event when deleting a property instead of "remove" because Matreshka.Array has an event with the same name, but called in another case[].forEach does not exist, an error is generated with the suggestion to subnet es5-shimeventName + eventHandler + context can only be added once per instance.Class function ( splice vs slice )MK.Array , replacing the previous one. There I will talk in more detail about the methods, how the elements of the array are rendered, about the “model” and how to pass options to the methods of the arrays.Source: https://habr.com/ru/post/231333/
All Articles