How to unravel noodles without getting depressed

    This article is not about your sweet interfaces on the react, hangar or what do you use there? This article is about situations where you have a bunch of jQuery noodles. No, let it be mountains of jQuery noodles wrapped in bacon views.

    The article uses the Backbone.View.Elements library

    Problem One: Low Expression Selectors


    We all saw noodles, we all know: noodles in JSе - probably not everything is good in layout. And if this is so, then the code, most likely, is teeming with obscure manipulations with the house. It is difficult to read such a code, because it is necessary, without losing sight of the author’s thoughts about what is happening here, to keep in mind a bunch of slurred names for elements. So, let's give the code a little expressiveness:
    _selectors: function () {
        return {
            elemName: '.block__elem-name'
        };
    }
    
    Add all the selectors in one place and give an understandable name to the elements for which they are needed. By the way, we will choose them like this:
    this._elem('elemName');
    
    instead
    this.$('.block__elem-name');
    


    In our case, you can say that this added little expressiveness, but do not forget that you most likely do not have a project that uses BEM to name classes, but sweetly smelling over semantic selectors of the form
    ‘div > tr.row[data-active=”true”] a.red-Button’
    
    for buy buttons.

    In addition to the ability to select an element inside our view, we also got the opportunity to get the selector itself by name:
    this._selector('elemName');
    
    This is also necessary.

    Another advantage is that if the layout changes, we will only need to change the selector in one place, because we have reduced code duplication.

    Problem Two: Storing Items


    You know, it happens like this:
    $(‘div > tr.row[data-active=”true”] a.red-Button’).blahBlah();
    
    and after 10 lines like this:
    $(‘div > tr.row[data-active=”true”] a.red-Button’).anotherBlahBlah();
    

    Tearing a palm from your face, you will take it into a variable
    var $buyButton = $(‘div > tr.row[data-active=”true”] a.red-Button’);
    
    oh no, you have a Backbone - put it into a property
    this._$buyButton = this.$(‘div > tr.row[data-active=”true”] a.red-Button’);
    
    or have you already connected Backbone.View.Elements?
    this._$buyButton = this._elem(‘buyButton’);
    

    Really not worth it - _elemand so everything caches, so just
    this._elem(‘buyButton’);
    

    Caches, speak? What if everything changes?


    Yes, we also heard that there are two problems with programming. therefore
    this._findElem('elemName');
    
    looking without cache
    this._dropElemCache(‘elemName’);
    
    will clear the cache for a specific item, and
    this._dropElemCache();
    
    will clean your entire cache to shine when you realize that the time has come. For example, after rendering.

    Global elements


    We also wrapped the most commonly used elements in jQuery so as not to do this more than once in the application. Meet:
    this._$window;
    this._$body;
    this._$document;
    


    Problem Three: Imperative Styles


    It seems that there is a whole language to describe the styles, but no - that's just the point in the noodles you can find dyes:
    $(‘div > tr.row[data-active=”true”] a.red-Button’).css({color: ‘magenta’});
    
    Pepper all over with declarativeness and mix CSS well:
    .button_active {
      color: magenta;
    }
    
    And we took care of class manipulation. First, we denote all classes in one place:
    _classes: function () {
        return {
            activeButton: 'button_active'
        };
    }
    
    And then, you want - add a class
    this._addClass(‘activeButton’, ‘buyButton’);
    
    if you want - delete:
    this._removeClass(‘activeButton’, ‘buyButton’);
    
    if you want - switch:
    var condition = !!Math.round(Math.random());
    this._toggleClass(‘activeButton’, ‘buyButton’, condition);
    

    You can get a selector if the class is already described:
    this._selector(‘activeButton’); // returns ‘.button_active’
    
    and you can search for elements:
    this._elem(‘activeButton’);
    
    Just do not forget about the cache, because the active button is sure to change
    this._findElem(‘activeButton’);
    

    The fourth problem: when everything is complicated


    It happens that selectors and classes are formed dynamically:
    var id = 5,
        state = ‘highlighted’;
    $(‘.item[data-id=”’ + id + ’”]’).addClass(‘item_state_’ + state);
    
    Here complex selectors come into play:
    _classes: function () {
        return {
            itemInState: 'item_state_%s'
        };
    },
    _selectors: function () {
        return {
            itemById: '.item[data-id=%s]'
        };
    }
    
    Then the following will be true:
    this._class(‘itemInState’, ‘highlighted’); // вернет ‘item_state_highlighted’
    this._selector(‘itemInState’, ‘highlighted’); // вернет ‘.item_state_highlighted’
    this._selector(‘itemById’, 5); // вернет ‘.item[data-id=5]’
    

    And the manipulation described above will be performed as follows:
    var id = 5,
        state = ‘highlighted’;
    this._addClass([‘itemInState’, state], [‘itemById’, id]);
    
    The item_state_highlighted class will be added to the element found by the selector .item [data-id = 5]

    Terminal complexity selectors


    _classes: function () {
        return {
            item: 'item_%(mod)s_%(value)s'
        };
    }
    
    Each place has its own name
    this._elem(‘item’, {
      mod: ‘state’,
      value: ‘focused’
    });
    
    Find jQuery selector collection ‘.item_state_focused’

    Problem Five: Getting Data


    A bit of sugar for date attributes.
    this._data;
    
    Stores the data of the root element of the view. So if you havediv
    on which I initialize the view
    this._data[‘someIds’]; // вернет массив [5,6,7]
    
    And if the data is stored in a specific element, then it will help you
    this._getElemData(‘elemName’, ‘someIds’);
    
    In order to get all the data:
    this._getElemData(‘elemName’); // вернет {someIds: [5,6,7]}
    


    About installation and use


    GitHub: github.com/backbonex/backbone.view.elements
    todomvc using and without Backbone.View.Elements

    Also popular now: