我读过很多文章,这些文章表明我应该避免在HTML模板中添加复杂的逻辑, 所以我的问题是,如果我根据加载到页面的DATA的类型编写一个需要一些特定属性或类名的模块,是否应该在模块内部编写此层作为方法或错误的意识形态?
例如,在此代码中,我从JSON文件中加载数据
{
"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"
}
]
}
此模板
<section id="slideShow">
<script id="slideShow-template" type="text/template">
<ul>
{{#slideShow}}
<li class="{{{class}}}">
<img src="{{{img}}}" alt="{{{title}}}">
<a href="{{{link}}}">
<h1 class="slideShowTitle">{{title}}</h1>
<p class="slideShowDate">{{date}}</p>
<p class="slideShowDetail">{{detail}}</p>
</a>
</li>
{{/slideShow}}
</ul>
<nav>
{{#slideShow}}
<a href="javascript:;"></a>
{{/slideShow}}
</nav>
<a href="javscript:void(0)" class="prevSlide"></a>
<a href="javscript:void(0)" class="nextSlide"></a>
</script>
</section>
然后我写了这个
(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();
})();
我询问有关this.dataProcess()
的问题,该检查会检查数据对象以添加类名和属性
这是与服务器端和数据库无关的某种数据
应该保留在这里,还是结构错误?
答案 0 :(得分:0)
通常,当人们谈论避免在演示文稿中使用复杂的逻辑时,他们指的是业务逻辑。数据中的条件会改变处理流程。
在您的情况下,您所谈论的是表示逻辑,而不是业务逻辑,它绝对应该保留在您拥有的表示层中。
您应该避免的事情是,如果您具有控制逻辑,例如,如果要基于日期更改标题。这样的逻辑最好在服务器端的专用层内完成,以便可以重用/测试/强制执行。
我个人使用的测试是,如果我将整个应用程序改写为另一个交付渠道(例如胖客户端),逻辑是否有用,那是否是有用的逻辑?还是我必须对其进行重大更改?如果它在很大程度上保持完整(尽管有语言差异),那么它可能属于逻辑/服务/业务层中的服务器端。就您而言,您正在谈论修改CSS。它是特定于表示的,因此如果使用不同的表示层,则可能会大不相同。