Может войдёшь?
Черновики Написать статью Профиль

Новая переменная $loop в Laravel 5.3

перевод новое в 5.3

Давайте рассмотрим ещё одну новую возможность, появившуюся в Laravel 5.3.

Что такое директивы Blade?

Язык шаблонов Laravel Blade предоставляет нечто, называемое «директивы», которые представляют собой настраиваемые теги для часто используемых управляющих структур, начинающиеся с символа @. Если вы когда-нибудь писали шаблоны в Blade, то скорее всего знаете @if, @foreach и т.д.

Вообще, эти директивы управляющих структур просто эмулируют соотвествующие PHP-аналоги. Например, PHP@if(condition) — это то же самое, что и PHP<?php if (condition):.

Знакомство с переменной PHP$loop

В версии 5.3 директива PHP@foreach обрела немного суперсилы в виде переменной PHP$loop, которая доступна в каждом цикле PHP@foreach.

Переменная PHP$loop — объект stdClass, предоставляющий метаданные того цикла, в котором вы сейчас находитесь. Посмотрите на её свойства:

  • index — индекс текущего элемента в цикле от нуля; 0 означает «первый элемент»
  • iteration — индекс текущего элемента в цикле от единицы; 1 означает «первый элемент»
  • remaining — сколько элементов осталось в цикле; если текущий элемент первый из трёх, то вернётся 2
  • count — число элементов в цикле
  • first — логическое; первый ли это элемент в цикле
  • last — логическое; последний ли это элемент в цикле
  • depth — целое число; на каком уровне вложенности данный цикл; вернёт 1 для цикла, 2 для цикла в цикле, и т.д.
  • parent — если данный цикл находится внутри другого цикла PHP@foreach, вернёт ссылку на переменную PHP$loop для элемента родительского цикла; иначе вернёт null

Большинство из них довольно очевидны, а значит вы можете делать вот так:

PHP
<ul>
@foreach (
$pages as $page)
  <
li>{{ $page->title }} ({{ $loop->iteration }} / {{ $loop->count }})</li>
@endforeach
</
ul>

Но также вы получаете ссылку на родительские переменные PHP$loop, когда работаете с вложенными циклами. Вы можете использовать depth, чтобы определить, вложен ли цикл, и parent для получения переменной PHP$loop его родителя. Это открывает подобные возможности для использования шаблонов:

PHP
<ul>
@foreach (
$pages as $page)
  <
li>{{ $loop->iteration }}: {{ $page->title }}
    @if (
$page->hasChildren())
    <
ul>
    @foreach (
$page->children() as $child)
      <
li>{{ $loop->parent->iteration }}.{{ $loop->iteration }}:
          {{ 
$child->title }}</li>
    @endforeach
    </
ul>
    @endif
  </
li>
@endforeach
</
ul>

Вот и всё!

Как вы считаете, полезен ли этот материал? Да Нет

Комментарии (10)

tmanager

Это открывает подобные возможности для использования шаблонов:

PHP
<ul>
@foreach (
$pages as $page)
  <
li>{{ $loop->iteration }}: {{ $page->title }}
    @if (
$page->hasChildren())
    <
ul>
    @foreach (
$page->children() as $child)
      <
li>{{ $loop->parent->iteration }}.{{ $loop->iteration }}:
          {{ 
$child->title }}</li>
    @endforeach
    </
ul>
    @endif
  </
li>
@endforeach
</
ul>

Зачем таким образом пародировать программный код? Не лучше ли сочинить его в контроллере и кинуть в представление как параметр?

P.S. А я так и знал — не получится в MVC по-человечески разнести логику и оформление.

AlexeyMezenin

Контроллер имеет минимум логики, от вытягивает данные из модели и передает в представление. Представление — это не только оформление. Перечислять (итерировать) данные ты в контроллере будешь?

tmanager

Ну да. Раз уж пришлось работать в MVC (мне больше нравится мои собственные паттерны, но что делать — не кормят они...) — то очень поможет порядок: где что искать.

В моделях — ищем работу с базой(-ами).
В контрололерах — всю логику.
В представлениях — всё, что относится к вёрстке.

Птоэтому у меня представления короткие и почти лишенные логики. В них — верстка страницы.

Я поддерживабю проект, написанный другими разработчиками. Там представление — это «ад каннибалов». Вот чего я стараюсь избегать.

AlexeyMezenin

В контрололерах — всю логику.

Это не MVC.

И ты не ответил, ты в контроллере данные будешь итерировать? Т.е. ты в контроллере будешь лепить что-то вроде:

foreach ($page->children() as $child) {
      $a .= '<li>'.$child->title.'</li>';
}
Denys

по мне проще, если контроллер делегирует данные в переменную посредством функций, которые определенны в отдельном файле типа main_functions
а во view уже кидать отдельные массивы данных

Proger_XP
  1. P.S. А я так и знал — не получится в MVC по-человечески разнести логику и оформление.

У вас все посты совершенно в одном духе — как раньше было хорошо, как сейчас плохо. Причём без фактов и примеров, просто слова в вакууме.

Какая разница между представлением и логикой, если они пересекаются? Смысл их делить? Тогда уж писать всё в одном файле, как в WordPress, и не заморачиваться модными концепциями.

tmanager

У вас все посты совершенно в одном духе — как раньше было хорошо, как сейчас плохо

Да ладно. Ничего подобного в моём комментарии нет.

Какая разница между представлением и логикой, если они пересекаются?

Никакой. От себя добавлю — они всегда пересекаются. Ну кроме каких-то совершенно «учебных» случаев.

Смысл их делить?

Никакого.

Тогда уж писать всё в одном файле, как в WordPress

Я никогда в жизни не агитировал за WordPress.

и не заморачиваться модными концепциями

Ну почему. Просто модные концепции нужно пробовать на зуб.

AlexeyMezenin

Кстати, хочу поделиться очень полезным сниппетом, показывающим насколько $loop - полезная переменная. Перечисление данных массива, разделенных запятой, когда запятую в конце ставить не нужно:

@foreach ($arrayOrCollection as $value)
    {{ $loop->first ? '' : ', ' }}
    <span class="nice">{{ $value->first_name }}</span>
@endforeach
Proger_XP
  1. Перечисление данных массива, разделенных запятой, когда запятую в конце ставить не нужно

Только есть проблема с пробелами — т.к. у тебя там переводы строки и отступы, то в запятой + пробеле нет смысла, т.к. они и так подставляются. А вот убрать пробелы до запятой ты убрать не сможешь (если не ставить cssfont-size: 0 и т.д.).

Если контекст позволяет, то лучше решать через CSS (исчезает возможность копировать запятую, но иногда это даже полезно):

css.nice + .nice:before { content: ", "; }

Если нет, то нужно ставить запятую после блока, причём без пробелов/новой строки перед ней, а вот это уже не так красиво.

AlexeyMezenin

Проблем с пробелами «почти нет», много использовал в реальном проекте (не только с запятой). Где-то помню проблема была. Решил тем, что в span обернул. За пример с CSS спасибо.

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.