📜 ⬆️ ⬇️

(Archive) Matreshka.js - MK.Array

The article is outdated. The new documentation contains the most current information from this post. See Matreshka.Array .



(Remember, the repository is here )
')
Greetings to all. I ended the previous article on the fact that we may need an array of data. An array in the project Matreshka.js are instances of the class MK.Array . How are they different from ordinary arrays? Almost nothing. The MK.Array prototype contains all the methods that a “traditional” array has, the constructor takes the same arguments as the original Array , and the instances have several interesting features.

MK.Array is an array on steroids that can:


Remember the gif from the first article in the series?


When using MK.Array you need to remember 5 things:

0. The methods that came from Array to MK.Array not rewritten. MK.Array uses the built-in capabilities of the array, which means, firstly, the class code is very compact, and secondly, we avoid the bugs of incorrect implementation of the methods. This also means that many new methods will not work in Internet Explorer 8 unless you connect, say, es5-shim . When calling an unsupported method, an error is generated, the message of which will offer to connect this library.

The list of implemented methods was compiled when studying the Array prototype in the latest build of Chrome and the MDN documentation.

1. Methods that modify an instance, generate two events: "modify" and the name of the method. For example, after executing the .push method, not only "modify" generated, but also "push" . UPD : When adding elements, the event "add" generated, when deleting - "remove" .

 var mkArray = new MK.Array; mkArray.on( 'push', function() { alert( 'push' ); }); mkArray.on( 'modify', function() { alert( 'modify' ); }); mkArray.push( 42 ); 


List of modifying methods:


2. To avoid generating relevant events, use methods starting with silent . For example, if you want to add an element to an array, but want to avoid generating events, use silentPush (note that the name of the original method is written with a capital letter).

 var mkArray = new MK.Array; mkArray.silentPush( 42 ); 

A list of modifying methods that do not generate events when they are run:


3. The .forEach method, which in the prototype of the original Array returns undefined , in MK.Array returns itself:
 var mapped = mkArray .forEach( function() { ... }) .forEach( function() { ... }) .map( function() { ... }) ; 


4. Methods of the original Array , which modify the array and perform the secondary function, returning the length of the array ( .push , .unshift ) or the deleted element ( .pop , .shift ) ( UPD : Fixed in 0.1), in MK.Array return themselves. This allows you to build chains of methods (something that I have always lacked). Methods whose primary task is to return a value of another type work in the traditional way. This means that .indexOf returns a number, .toString - a string ...

 mkArray .push( 1, 2, 3, 4 ) .unshift( 0 ) .push( 5 ) .forEach( function() { ... } ) .sort() .reverse() ; 


It is very easy to compensate for this behavior, for example, for the .push method:
 var array = new Array( 1, 2, 3, 4 ), mkArray = new MK.Array( 1, 2, 3, 4 ), arrayLength, mkArrayLength; arrayLength = array.push( 6, 7 ); mkArray.push( 6, 7 ); mkArrayLength = mkArray.length; 


5. Iterator methods ( .forEach , .map , .filter , ...) take as their first argument a function whose third argument is an instance of the native array. The feature of the eighth Donkey does not allow the use of Array.prototype[ method ].apply in the context of the Nested doll, therefore, the launch of the methods is as follows:
1. An instance of MK.Array converted to an Array instance.
2. The Array.prototype[ name ].apply( array, arguments );
3. The MK.Array instance is cleared and updated with the resulting Array .

 mkArray.forEach( function( item, index, array ) { console.log( array === mkArray ); // false }); 


This is a feature of the implementation of the Matryoshka, which can cause confusion among experienced programmers. Do not rush to write an angry comment. If Habra is interested, I will tell the most important thing: how the Nested doll works.

UPD : In version 1.0, this feature will be fixed due to the abandonment of support for IE8

Inheritance

Nested array is inherited in the same way as any class inherited from Nested doll:
 var MyArray = Class({ 'extends': MK.Array, constructor: fucntion() { this.initMK(); } }); 

The .initMK method, in this case, besides the initialization of the main pseudo-private Matryoshka properties, adds event handlers necessary for the array and is required to run when inheriting.

The text under the spoiler has lost relevance after the release of the Matryoshka 0.1. You can not read it.
Practical application

MK.Array itself is a ready-to-use class that will add sugar to any application. There is only one “but”: a matryoshko array does not know how to bind data to the elements of an array. .bindElement course, you can .bindElement an element to an index using a .bindElement , but obviously it makes little sense: indexes are constantly changing when modified. What to do if you have, say, a list that needs to be updated when the array changes. In this case, you need to track the necessary methods and change the DOM manually. For example, if the application involves adding and removing elements, you need to listen to the events of "push" and "splice" , the only question is what your application needs.

The GIF in the beginning of the post is a demonstration of the work (so far) of the undocumented MK.DOMArray plugin , which, in response to changes in data, automatically changes the DOM. The plugin was created as an experiment, demonstrating the capabilities of the Matryoshka and to get closer to the idea that the DOM should update itself when the data changes. But the experiment was so successful that, perhaps, the plugin code will be MK.Array into the MK.Array code. Changes in the DOM are optimal: when adding objects to an array, new elements are added to the page, deleted when deleted, sorted. This is me to the fact that the table is not redrawn anew, but responds consistently.

Here the matreshka-array (or rather its descendant: MK.DOMArray ) in the example can be called the analogue of the Collection in Backbone, and its elements - the analogue of the Model. An example can be seen here: jsbin.com/aZEseWE/16 (it was from this example that the gif was recorded). And here: jsbin.com/eQomoJe/9 is a more ascetic option. It does not override built-in methods. I prefer the second method, despite the apparent redundancy.

MK.DOMArray works in this way: when adding objects (to the beginning, end, middle ... all the same), it checks whether the "self" has a .renderer method and, if it exists, inserts the returned element into the page tree and raises an event on the object "render" .
 var Example = Class({ 'extends': MK.DOMArray, constructor: function() { this //   .initMK() //   .bindElement( this, 'table tbody' ) ; }, renderer: function( object ) { //     .    ,   return '<tr><td class="a"></td><td class="b"></td><td class="c"></td></tr>'; } }); 

The task of the added object is to capture the "render" event and bind the elements inside the element bound to "__this__" .
 var ExampleObject = Class({ 'extends': MK.Object, constructor: function( o ) { this .initMK() .jset( o ) .on( 'render', function( evt ) { this //    'render' — ,    //  MK.DOMArray    HTML    ? //    ( )   ,  , //          .bindElement( this, evt.el ) //    .bindElement({ a: this.$( '.a' ), b: this.$( '.b' ), c: this.$( '.c' ) }, MK.htmlp ) ; }) ; } }); 



Idea
Here and the plugin, which works exclusively with tables. Perhaps it will work like this:
 var table = MK.Table({ table: '.my-table' rows: [{ title: 'A', key: 'a' }, { title: 'B', key: 'b' }] }); table.push({ a: 'Fuck', b: 'Yeah' }); 



At the end of the cycle


Matryoshka is a compact, easy-to-learn framework that will continue to evolve. Regardless of the level of training of the programmer, Matryoshka is easy to learn and, most likely, is a great start when moving to structured code by beginners. Compact and extensible gives a bunch of ideas for plugins and add-ons. Over time, the dependence on jQuery ( UPD : Already removed), support for Internet Explorer 8, improved performance, and more ... will be removed

Thank you for your attention, all good.

PS The README repository now has a roadmap .

Source: https://habr.com/ru/post/198212/


All Articles