📜 ⬆️ ⬇️

Cones on matryoshka

Recently a new version of Matreshka.js has been released.

image

The documentation on the very first page says that even a beginner can figure it out, the framework is very simple.
')
So says the documentation, but in fact there are pitfalls, especially considering “for beginners” and examples in the documentation that are confusing.

In this experiment, I decided to abandon completely any other library (in particular, JQuery), so as not to write everything out of habit.

Task




Legend


I am a lazy, unpretentious SEO in an office, and often I have to choose and filter phrases. A lot of money has already been invested in collecting these, and I'm so lazy simple that I want to automate the filtering at least somehow.

The process has begun


What should happen:

Picture
image

So, first of all, let's jot down html:

<div id="m"> <div class="button" id="delPlus"> </div> <div class="button" id="minus-words-open">-</div> <div id="mWordsContainer"> <div class="button" id="myMinus"> <input type="text"></div> <div class="button" id="selfhands"> </div> <div class="button" id="bu">/</div> <div class="button" id="forfree"></div> <div class="button" id="otz"></div> <div class="button" id="video"></div> <div class="button" id="foto"></div> </div> </div> <div id="c"> <div class="button" id="loadWords">  </div> <div id="loadList"> <textarea></textarea> <div class="button" id="startLoad"></div> </div> <ul id="wordList"></ul> </div> 

It is not necessary to focus on it, in this post we look at the nested doll.

And here is the first task - to figure out why bindNode () is still needed:
Due to inexperience, I rushed to bind all the buttons and fields, believing that this is akin to setting a variable.
And in fact, this is one of the functions - binding to a variable, but according to a certain logic, which you set yourself.

Having read this section of the documentation several times, I, as it turned out, did not understand the meaning of bindNode (), therefore I will give a visual example:

image

We specify the name of our future variable as the first argument (rather, it is even a pointer, but we will not complicate the terminology).

Every time the action specified in on occurs (in our case, on: 'click'), the return value will be passed to our “variable”, that is, the class (in fact, it is not completely variable, but more on that below).

And vice versa, each time the “variable” changes by third-party methods, for example:

 this.class = 'value'; app.class = 'value2'; 

The setValue (arg) method is called, in which the new value of the “variable” is passed as an argument.

Pointer


In fact, what we have called the variable so far (as part of this article) is in fact a pointer (even plural). That is, this “variable” refers to all those objects to which we tied it.

  this.bindNode('variable','#loadList textarea'); //   this.bindNode('variable','#loadList'); //    this.bindNode('variable','#myMinus input'); //  - 

What does this mean?
Yes, when changing the value of a variable in any way, we will call the setValue () method on each bound object.

If some object itself has changed the value of the variable using the getValue () method (on the on: 'click' event), then setValue () is called on all other attached objects.

: sandbox


The documentation is well described array Matreshka.Array, I will not dwell on it.
Is that more about what a sandbox.

Sandbox is a sandbox (as is clear from the documentation), but what does it give us?

A living example is when creating an array model, we will write a couple of lines to bind actions for specific elements of our array.

  this.on('render',function(){ this.bindNode('close',':sandbox i'); this.on('click::close',function(){ this.sandbox.className = 'disabled'; }); }); 


: Sandbox here acts as a pointer to the current DOM element. That is, this is the sandbox, everything happens within it.

Closer to the point


With the knowledge we have, you can add a list of phrases to the list:

  this.bindNode('preList','#loadList textarea'); //   $b('#startLoad').on('click',function(){ wordList.recreate(); var preArr = app.preList.split("\n"); for(key in preArr){ wordList.push({ value:preArr[key] }); } }); 

Full array reference code
 var listModel = Matreshka.Class({ //   'extends': Matreshka.Object, constructor: function(data){ this.jset(data); this.on('render',function(){ this.bindNode('value',':sandbox .value',Matreshka.binders.innerHTML()); this.bindNode('class',':sandbox',{ //  class  on: 'click', getValue: function(){ return this.className; }, setValue: function(v){ //  : this.class = value this.className = v; }, initialize: function(){ $b(this).on('click',function(){ $b(this).toggleClass('active'); }); } }); this.bindNode('close',':sandbox i'); this.on('click::close',function(){ this.sandbox.className = 'disabled'; }); }); } }); var listArray = Matreshka.Class({ //   'extends': Matreshka.Array, Model: listModel, itemRenderer: '<li><span class="value"></span><i></li>', constructor: function(){ this.bindNode('sandbox','#wordList'); //    }, minus: function(search){ if (search.length < 1) return; this.each(function(item, index){ if ((typeof search) == 'object'){ for(key in search){ if (item.value.toUpperCase().indexOf(search[key].toUpperCase()) + 1){ item.class = 'disabled'; }; } }else{ if (item.value.toUpperCase().indexOf(search.toUpperCase()) + 1){ item.class = 'disabled'; }; } }); } }); var wordList = new listArray; //    



Filtration


What do you need? It is necessary to remove unnecessary.
This is where the first disappointment lies: it could not figure out how to remove a specific element of the array.
There is a splice, but to use it, you need to know the index of the array element.
Well, there is an index () for this when working with the DOM (given that we have ul li and our array connected).
BUT! He is in jQuery, but not in the balalaika. Having checked this way and that, I tried various options and came to the conclusion that I would have to not remove the elements from the array, but hide their display (display: none).

  this.bindNode('close',':sandbox i'); this.on('click::close',function(){ this.sandbox.className = 'disabled'; }); 

Well, it's great to remove the pens on the cross, but it's time to do at least something automatic, because that was the goal.

Negative words


Minus words - these are words whose presence is not necessary.
In our case, we will delete phrases in which these negative keywords are present.
How to find them? The selector: contains () and its extension: Contains () immediately comes to mind (case-insensitive search, you must write yourself).

But here the second disappointment - such a selector is not supported by the balalaika. And therefore it is necessary to do brute force and comparison:

  minus: function(search){ if (search.length < 1) return; this.each(function(item, index){ if ((typeof search) == 'object'){ for(key in search){ if (item.value.toUpperCase().indexOf(search[key].toUpperCase()) + 1){ item.class = 'disabled'; }; } }else{ if (item.value.toUpperCase().indexOf(search.toUpperCase()) + 1){ item.class = 'disabled'; }; } }); } 

Do not forget that some negative words can be written differently (bu, b, b / y), so we will consider the possibility of transmitting an array (native).

Conclusion


What I wanted to sharpen, sharpened, the full code, if you 're interested, on the githaba . Result .

I summarize


Upset only balalaika, to the doll matryoshka no complaints.
Although the similarity of the names suggest the idea of ​​common developers. Upset, such needs are not included in the balalaika.

The code turned out to be less than on JQuery (although it did on it for a long time and was rotten), the library itself weighs more than 2 times less.

Conclusion: I liked it, I will use it.
With the balalaika has not yet resolved the issue.

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


All Articles