Вход

Просмотр полной версии : Возможно ли вставить элемент между элементами, создаваемыми ng-repeat?


LittlePony
04.01.2014, 11:56
Добрый день.
Есть задача: получить код примерно такой структуры:


<div class="row">
<div class="col-sm-6 col-md-4">эти</div>
<div class="col-sm-6 col-md-4">блоки</div>
<div class="clearfix visible-sm"></div>
<div class="col-sm-6 col-md-4">могут</div>
<div class="clearfix visible-md"></div>
<div class="col-sm-6 col-md-4">быть</div>
<div class="clearfix visible-sm"></div>
<div class="col-sm-6 col-md-4">разной</div>
<div class="col-sm-6 col-md-4">высоты</div>
</div>


Здесь блоки <div class="col-sm-6 col-md-4"> содержат контент, и их логично создавать при помощи ng-repeat:


<div class="row">
<div class="col-sm-6 col-md-4" ng-repeat="item in content">{{item}}</div>
</div>


При этом блоки с классом clearfix выполняют исключительно оформительскую задачу, контента не содержат, и на уровне шаблона должны внедряться через определённое количество блоков с контентом (через три на десктопах и через два на планшетах). То есть, так я например достигаю нужного результата в django-шаблоне:

<div class="row">
{% for item in content %}
<div class="col-sm-6 col-md-4">{{ item }}</div>
{% if forloop.counter|divisibleby:3 %}
<div class="clearfix visible-md"></div>
{% endif %}
{% if forloop.counter|divisibleby:2 %}
<div class="clearfix visible-sm"></div>
{% endif %}
{% endfor %}


Сейчас хотелось бы достичь такого же эффекта в шаблоне на ангуляре. Однако ума не приложу, как это сделать. Ведь ng-repeat повторяет определённый элемент, а уже что-то делать позволяет только внутри этого элемента.
Возможно ли вообще в шаблоне в цикле ставить разделители между элементами, а не внутри их?

LittlePony
04.01.2014, 13:26
Простите, вопрос действительно глупый, поскольку решается более вдумчивым чтением документации. Но если у кого ещё возникнет такой же, вот работающий пример:


<div class="row">
<article class="col-md-4 col-sm-6" ng-repeat-start="article in productsData.ARTICLES">
<figure class="preview-image">
<img ng-src="{{article.PREVIEW_PICTURE.src}}">
</figure>
<hgroup>
<div class="section-name">{{productsData.SECTIONS[article.SECTION_ID].NAME}}</div>
<h4>{{article.NAME}}</h4>
</hgroup>
<div class="article-text">{{article.PREVIEW_TEXT}}</div>
</article>
<div class="clearfix hide" ng-repeat-end ng-class="separatorClasses($index)"></div>
</div>


где функция separatorClasses определена в контроллере:


$scope.separatorClasses = function(index){
var classes = [],
i = index+1
if(i%2==0) {
classes.push('visible-sm')
}
if(i%3==0) {
classes.push('visible-md')
classes.push('visible-lg')
}
return classes
}


Так пример, конечно, работает, но сама идея css-классов в контроллере мне совсем не нравится, грубо нарушает MVC на мой взгляд.
Но как поступить правильнее?

dolpheen
04.01.2014, 21:26
К сожалению, конкретного решения, привести не могу (только недавно начал изучать фреймворк).
По-моему, решение уже кроется в Вашем же ответе, про то, что манипулировать DOMом рекомендуется не из контроллеров, а из директив. Например, обернуть DIVы ng-repeat в элемент-директиву, и реализовать в ней вставку необходимых оформительских DIVов.
Или, если брать пример выше с ng-repeat-end, то встроить проверку классов в выражение директивы.
ng-class="{'visible-sm': !(($index+1) % 2),'visible-md': !(($index+1) % 3)}"

dolpheen
08.01.2014, 16:59
Вставка разделителей через директиву


<script>

angular.module('myApp', [])
/* Код директивы */
.directive('divider', [ function () {
return {
link: function ( scope, elem, attr) {
var si = scope.$index + 1;
if( !(si % 2) ) angular.element(elem).after('<div class="clearfix visible-sm">--SM divider--</div>');
if( !(si % 3) ) angular.element(elem).after('<div class="clearfix visible-md">--MD divider--</div>');
}
};
}]);
</script>

/* Репитер с нашей директивой */
<div ng-repeat="i in [0,1,2,3,4,5,6,7]" divider>
Item {{i}}
</div>

Код на Plunker
http://embed.plnkr.co/bFjfAQTAGQL8y1VEuuxb/preview