Javascript-форум (https://javascript.ru/forum/)
-   Angular.js (https://javascript.ru/forum/angular/)
-   -   Возможно ли вставить элемент между элементами, создаваемыми ng-repeat? (https://javascript.ru/forum/angular/44053-vozmozhno-li-vstavit-ehlement-mezhdu-ehlementami-sozdavaemymi-ng-repeat.html)

LittlePony 04.01.2014 11:56

Возможно ли вставить элемент между элементами, создаваемыми ng-repeat?
 
Добрый день.
Есть задача: получить код примерно такой структуры:

<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


Часовой пояс GMT +3, время: 08:37.