mardi 8 janvier 2019

Where to put data / logic layer in front end

I've read many articles which indicated that I should avoid putting complex logic into my HTML template, so my question is if I write a module which needs some specific attribute or class name based on the type of DATA loading to my page should I write this layer inside of my module as a method or its a wrong ideology ?

for example in this code Im loading DATA from a JSON file

{
    "slideShow": [
        {
            "img": "aaaaaaaa.jpg",
            "link": "aaaaaaaaa.html",
            "title": "aaaaaa",
            "date": "aaaaaaaa",
            "detail": "aaaaaaaaaaaaa"
        },
        {
            "img": "bbbbbbbbbbb.jpg",
            "link": "bbbbbbbbbbb.html",
            "title": "bbbbbbbbbbb",
            "date": "bbbbbbbbbbbbb",
            "detail": "bbbbbbbbbbbbb"
        },
        {
            "img": "ccccccccccc.jpg",
            "title": "ccccccc",
            "date": "ccccccccccccc"
        },
        {
            "img": "dddddddddd.jpg",
            "title": "ddddddddd",
            "date": "dddddddddd",
            "detail": "dddddddddd"
        }
    ]   
}

then I wrote this

(function() {

    var slideShow = {

        slideShow: [],

        importData: function() {
            var xhr = new XMLHttpRequest(),
                url = 'data/slideShow.json',
                _self = this,
                result;
            xhr.onreadystatechange = function() {
                if(this.readyState == 4 && this.status == 200) {
                    result = JSON.parse(this.responseText);
                    _self.slideShow = result.slideShow;
                    _self.dataProcess();
                    _self.init();
                }
            };
            xhr.open('GET', url, true);
            xhr.send();

        },

        dataProcess: function() {
            this.slideShow.forEach(function(element, index) {
                element.class = '';
                if(!element.detail) {
                    element.class += 'noDetail ';
                }
                if(!element.link) {
                    element.link = 'javascript:void';
                    element.class += 'noLink ';
                }
                element.class = element.class.replace('undefined', '');
            });
        },

        init: function() {
            this.render();
            this.cacheDom();
            this.bindEvents();
            this.autoRun();
        },

        bindEvents: function() {
            this.$el.addEventListener('click', this.actionEvent.controlDirection.bind(this));
            this.$nav.addEventListener('click', this.actionEvent.selectSlide.bind(this));
        },

        render: function(cacheDom) {
            var data = {
                slideShow: this.slideShow
            };
            this.$el = document.getElementById('slideShow');
            this.template = document.getElementById('slideShow-template').innerHTML;
            this.$el.innerHTML = Mustache.render(this.template, data);
        },

        cacheDom: function() {
            this.$ul = this.$el.querySelector('ul');
            this.$li = this.$ul.querySelectorAll('li');
            this.$nav = this.$el.querySelector('nav');
            this.$a = this.$nav.querySelectorAll('a');
            this.$next = this.$el.querySelector('.nextSlide');
            this.$prev = this.$el.querySelector('.prevSlide');
        },

        autoRun: function() {
            this.$ul.style.left = '0';
            this.$ul.style.width = this.slideShow.length * 100 + '%';
            this.$li.forEach(function(element) {
                element.style.width = (100 / this.slideShow.length) + '%';
            }.bind(this));
            this.$a[0].classList.add('activated');
            this.autoTimer();
        },

        calc(direction, index) {
            this.left = parseInt(this.$ul.style.left);
            if(direction) {
                this.newLeft = this.left + (direction * 100);
                this.index = this.newLeft / 100;
            } 
            else {
                this.index = index;
                this.newLeft = index * 100;
            }
            if(this.newLeft > ((this.slideShow.length - 1) * 100)) {
                this.index = 0;
                this.newLeft = 0;
            } else if(this.newLeft < 0) {
                this.index = (this.slideShow.length - 1);
                this.newLeft = ((this.slideShow.length - 1) * 100);
            }
        },

        autoTimer: function() {
            this.timer = setTimeout(function() {
                this.transitSlide(+1);
            }.bind(this), 3000);
        },

        transitSlide: function(direction, index) {
            this.$el.removeEventListener('click', this.actionEvent.controlDirection);
            this.calc(direction, index);
            this.$ul.classList.add('fade');
            setTimeout(function() {
                this.changeSlide();
                this.bindEvents();
            }.bind(this), 700);
        },

        changeSlide: function() {
            clearTimeout(this.timer);
            this.autoTimer();
            this.$a.forEach(function(element) {
                element.classList.remove('activated');
            });
            this.$a[this.index].classList.add('activated');
            this.$ul.style.left = this.newLeft + '%';
            this.$ul.classList.remove('fade');
        },

        eventHandling: function() {
            clearTimeout(this.timer);
            event.stopImmediatePropagation();
            event.preventDefault();
        },

        actionEvent: {

            controlDirection: function() {
                this.eventHandling();
                if(event.target == this.$next) {
                    this.transitSlide(+1);
                } else if(event.target == this.$prev) {
                    this.transitSlide(-1);
                }
            },

            selectSlide: function() {
                this.eventHandling();
                this.$a.forEach( function(element, index) {
                    if((event.target == element) && (!element.classList.contains('activated'))) {
                        this.transitSlide(false, index);
                    }
                }.bind(this));
            }

        }

    };

    slideShow.importData();

})();

Im asking about this.dataProcess() which checks the data object to adding classnames and attributes this is some sort of data which is not relevant to server side and database

shoud I keep it here or my structure is wrong ?

Aucun commentaire:

Enregistrer un commentaire