Hello. 5 months have passed since the last publication of the series of articles on the Matryoshka. Since then, a small number of bugs was fixed, several handy features appeared, including under the influence of your comments, the project found a sponsor in the face of Shooju , received a logo and a normal, non-bootstrap site.<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 = ''; MK#addDependence means that I’m talking about the addDependence method, an instance of the MK class.addDependence calculates the value of the property in advance, when you change the data on which the property depends. You need to work very carefully with the getter, since relatively heavy calculations can greatly affect the performance of your code. “Dependencies,” in turn, are no different in terms of resource consumption from the usual processing of data change events and are, in fact, syntactic sugar over them. In addition, the method is another step towards self-documenting code.f always be the sum of the properties a, b, c, d, e . this.on( 'change:a change:b change:c change:d change:e', function() { this.f = this.a + this.b + this.c + this.d + this.e; }); this.addDependence( 'f', 'abcd e', function() { return this.a + this.b + this.c + this.d + this.e; }); this.addDependence( 'f', 'abcd e', function( a, b, c, d, e ) { return a + b + c + d + e; }); 'change:' heaps)a, b, c, d, e do something,” and the second way: “add the dependence of property f on properties of a, b, c, d, e ". Feel the difference?silent flag, the first option will not work. this.on( 'change:a change:b', function() { this.p = ( this.a + this.b ) * 2; }); // 2 this.addDependence( 'p', 'a b', function() { return ( this.a + this.b ) * 2; }); this.set({ a: 2, b: 3 }, { silent: true }); ... then in the first version, p will not change, in the second, it will change.p , and one of the properties that p depends on changed with the silent flag, then, as expected, the change handler p will not be called. this.on( 'change:p', function() { /* ... */ } ); this.set( 'a', 12, { silent: true }); // "p" "" this.addDependence( 'a', [ instance1, 'bc d', instance2, 'ef g', this, 'hij' ], function() { /* ... */ }); a , which should always be a string and nothing else. Let's try to solve this problem using the standard toolkit: // - this.on( 'change:a', function() { if( typeof this.a !== 'string' ) { this.a = String( this.a ); } }); // - 1 this.on( 'change:a', function() { if( typeof this.a === 'string' ) { /* ... */ } }); // - 2 this.on( 'change:a change:b', function() { if( typeof this.a === 'string' ) { /* ... */ } }); // this.a = 123; a to a string, and the last two handlers are forced to check whether a is a string, since the converter handler starts all the handlers (including itself) again. Wandering around in search of a solution, such as the event beforechange:%% , it was decided to introduce a new concept into the framework - “intermediary”.MK#setMediator is simple: the first argument is the key for which you want to set the mediator, the second argument is the function that should return the new value of the property. Alternative syntax: a key-mediator object is passed to the method in case you want to attach several mediators to a class at once.a should always be a string, and the property b should always be an integer (or NaN ) this.setMediator( 'a', function( value ) { return String( value ); }); this.setMediator( 'b', function( value ) { return parseInt( value ); }); this.setMediator( 'a', String ); this.setMediator( 'b', parseInt ); MK#setMediator with the same property will block the old pick. In order to remove the "intermediary", instead of the function, you can pass null . mk.setMediator({ percentageValue: function( v ) { return v > 100 ? 100 : v < 0 ? 0 : v; }, stringValue: String, integerValue: parseInt }); NaN ). Developing a thought, you can create a property that is always true or false, you can create a property that will always be an instance of some class ... var mkArray = new MK.Array( 1, 2, 3, 4, 5 ); mkArray.setItemMediator( function( value ) { return String( value ); }); mkArray.push( 6, 7 ); mkArray.unshift( true, {} ); console.log( mkArray.toJSON() ); // [ "true", "[object Object]", "1", "2", "3", "4", "5", "6", "7" ] null . mkArray.setItemMediator( null ); mkArray.setItemMediator( String ); input[type="text"] and textarea now listening to the 'paste' event, not just the 'keyup' . safron : article commentinput[type="checkbox"] and input[type="radio"] now listening to the 'keyup' event. This means that you can work with these elements from the keyboard when you bind data to them (the same comment).
jQuery . In my opinion, jQuery is a great library, but it loses its relevance in new browsers. Now, if there is no jQuery on the page, it replaces the mini library, which I called “Balalaika” (note: only if it is missing; if jQuery connected, then jQuery is still used).Array.prototype , so the developer has access to all the methods that the array has, plus jQuery compatible methods for working with classes ( addClass , removeClass , hasClass ), events ( on , off ), parsing HTML ( parseHTML ) and others. $b( 'div' ).forEach( function(){ /* ... */ } ); $b( '.blah-blah', context ).is( 'div' ); $b( 'input[type="text"]' ).on( 'keydown', handler ); this (key "__this__" , see previous articles). The method was created for simplified work with individual elements, but not with collections of elements. this.select( '.blah-blah' ); this . Does the same thing as the $ method (dollar sign). MK#selectAll created for completeness of the set of methods: if there is a “select” method ( MK#select ), then there must be a “select all” method. this.selectAll( '.blah-blah' ); // , this.$( '.blah-blah' ); var x = this.pull( 3 ); splice . var x = this.splice( 3, 1 )[ 0 ]; true in instances of the corresponding classes var mkObject = new MK.Object(); alert( mkObject.isMK && mkObject.isMKObject ); // true undefined (or nothing is passed).MK.Array plug-in was MK.DOMArray , which was mentioned in the article about MK.Array . That is, the functionality that reflected the "attention drawing" gif works out of the box. Let me remind you that the MK.DOMArray plugin changes the DOM automatically when the array is changed (add, delete, sort ...).Model property (which will be similar to the model from Backbone ). This feature will be syntactic sugar over the mediator of the array element.initMK method. Not kosher.EventTarget .MK#addDependence for dependencies on other instances of classes (as described above).value property is always a string, so that we don’t put it there, the valueAsNumber property valueAsNumber always a number that depends on the string value ...Source: https://habr.com/ru/post/217241/
All Articles