Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 23.06.2017 12:54:27

Blade, отрисовать (получить Html разметку) только одну секцию

Есть шаблон допустим:

<!-- Хранится в resources/views/layouts/app.blade.php -->
<html>
  <head>
    <title>App Name - @yield('title')</title>
  </head>
  <body>
    @section('sidebar')
      Это главная боковая панель.
    @show

    <div class="container" id="area">
      @yield('content')
    </div>
  </body>
</html>

И есть реализация в с формой допустим:

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @parent

    <p>Это дополнение к основной боковой панели.</p>
@endsection

@section('content')
    <form method="POST">...</form>
    <div>тут вывожу ошибки если они есть..</div>
@endsection

Если я допустим хочу реализовать это через AJAX, загружается страница, я ввожу данные, через AJAX они отправляются на сервер и если там есть ошибки то я на стороне сервера отрисовываю только то что содержится в файле layouts.app.blade.php, а точнее только то что содержится в секции content, и отправить обратно, а там уже JS заменит содержимое div с id = area на то что пришло, как такое реализовать? как отрисовать только секцию content?

Изменено GTX (23.06.2017 12:55:14)


Изучаю Laravel, до этого дела с фреймворками не имел.
Печальные познания в английском.

Не в сети

#2 23.06.2017 13:15:50

Re: Blade, отрисовать (получить Html разметку) только одну секцию

Не надо ничего на сервере отрисовывать. Нужно отправить ответ в виде JSON с описанием ошибки, а в JS его поймать и вставить в нужное место.

if (ошибка) {
   return response()->json(["success" => false, "message" => "Ошибся маленько!"]);
}

Не в сети

#3 23.06.2017 14:49:22

Re: Blade, отрисовать (получить Html разметку) только одну секцию

Sergant210, печально, отрисовать не составляет труда, вставить тоже, минимум труда (кода в JS), а по вашему варианту гемороиться с кривым JS.


Изучаю Laravel, до этого дела с фреймворками не имел.
Печальные познания в английском.

Не в сети

#4 23.06.2017 15:18:51

Re: Blade, отрисовать (получить Html разметку) только одну секцию

GTX прав, вместо того чтобы держать логику отрисовки и код шаблона сразу на двух сторонах (PHP/JS) лучше на стороне сервера отдавать по AJAX сразу тот же HTML, который генерируется и при обычном запросе, только без обёртки для целой страницы. Нормальная практика.

Не в сети

#5 23.06.2017 15:33:03

Re: Blade, отрисовать (получить Html разметку) только одну секцию

Proger_XP? так можно это как то сделать? потому что мне на ум приходят какие то совсем костыли, что аж страшно представить.
что то типа в файле реализации подключать еще 1 фал как раз с  этой формой, т.е. получается какая то такая хрень:
Реализация шаблона:

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @parent

    <p>Это дополнение к основной боковой панели.</p>
@endsection

@section('content')
    @include('form')
@endsection

А уже в файле form держать эту форму без всяких extends, а в случае необходимости получить форму я просто делаю рендер файла form.
Но это ппц какой то.


Изучаю Laravel, до этого дела с фреймворками не имел.
Печальные познания в английском.

Не в сети

#6 23.06.2017 15:42:03

Re: Blade, отрисовать (получить Html разметку) только одну секцию

Sergant210 пишет:

печально, отрисовать не составляет труда, вставить тоже, минимум труда (кода в JS), а по вашему варианту гемороиться с кривым JS.

ну кривой он или нет уже зависит от того что его напишет smile вообще это более разумный вариант чем html гонять туда-сюда

Proger_XP пишет:

прав, вместо того чтобы держать логику отрисовки и код шаблона сразу на двух сторонах (PHP/JS) лучше на стороне сервера отдавать по AJAX сразу тот же HTML, который генерируется и при обычном запросе, только без обёртки для целой страницы

это тоже неплохой вариант, но есть один немаленький недостаток – все обработчики, которые на форме лежат удалятся вместе с html-ем формы. обычно после отправки возвращается форма с подсвеченными полями и сообщениями об ошибке – так вот если на клиенте работает валидатор (типа jquery.validation) – после такой подмены валидатор на форму можно будет добавлять заново. и вот тут как раз выходит тот самый «кривой код» – потому что в форме уже есть ошибки, о которых валидатор не знает, но добавит свои когда форма будет заполняться пользователем дальше – для того чтобы подружить одно с другим – там столько лапши придётся навешать…

в то же время в ларавеле уже есть валидация форм в виде Form Requests, и у них как раз для случая с использованием аякса уже есть стандартный json-ответ при ошибках валидации – у такого ответа будет код 422 и в теле – json-ответ с идентификаторами полей и текстами ошибок. учитывая что многие плагины-валидаторы стандартно расширяются для отображения ошибок с сервера – мне кажется это самый простой и правильный способ работы с аякс-формами

Не в сети

#7 23.06.2017 17:40:52

Re: Blade, отрисовать (получить Html разметку) только одну секцию

Proger_XP пишет:

GTX прав, вместо того чтобы держать логику отрисовки и код шаблона сразу на двух сторонах (PHP/JS) лучше на стороне сервера отдавать по AJAX сразу тот же HTML, который генерируется и при обычном запросе, только без обёртки для целой страницы. Нормальная практика.

Дело в том, что в варианте GTX javascript кода будет не меньше и он будет сложнее:
1. Рендер формы на сервере.
2. Форму нужно переслать на клиент.
3. Нужно распарсить ответ.
4. Всунуть форму в DOM.
Возможные проблемы описал constb.

Мой вариант:
1. Гоним JSON с ошибками на клиент.
2. Вставить сообщение об ошибке в DOM (div id="error").

В итоге не теряем на рендере, на пересылке кода формы (существенно для мобильных) и на распарсивании кода. И если на поля навешаны JS плагины типа bootstrap mask, datetime, select2 и т.п., не надо заново их инициализировать.

Изменено Sergant210 (23.06.2017 17:45:13)

Не в сети

#8 23.06.2017 17:48:48

Re: Blade, отрисовать (получить Html разметку) только одну секцию

  1. что то типа в файле реализации подключать еще 1 фал как раз с этой формой, т.е. получается какая то такая хрень:

Я тоже навскидку кроме как отделения формы в отдельный шаблон ничего предложить не могу. Отдаёшь страницу по AJAX — используешь отдельный шаблон, без AJAX — шаблон + шаблон полной страницы.

  1. но есть один немаленький недостаток – все обработчики, которые на форме лежат удалятся вместе с html-ем формы.

Вообще-то нормальная практика это вешать обработчики не на конкретные элементы страницы, а на всю страницу с селектором. Это позволяет делать любые манипуляции со страницей без потери обработчиков (но, естественно, с потерей данных — $.data()).

js$(document).on('click', 'a#link', function ...)

// а не
$('a#link').on('click', function ...)

Это если на фронтенде голый jQuery. Если там Backbone или ещё какой-то компонентный фреймворк — то обычно есть метод вроде bind() для перепривязки обработчиков.

  1. учитывая что многие плагины-валидаторы стандартно расширяются для отображения ошибок с сервера – мне кажется это самый простой и правильный способ работы с аякс-формами

Зависит от того, что используется на фронтенде. В общем случае в PHP во всех отношениях проще отдавать с сервера HTML.

Не в сети

#9 23.06.2017 17:53:13

Re: Blade, отрисовать (получить Html разметку) только одну секцию

  1. 1. Рендер формы на сервере.

…не отличается от рендеринга обычной страницы.

  1. 2. Форму нужно переслать на клиент.

…не отличается от пересылки обычной страницы.

  1. 3. Нужно распарсить ответ.

Зачем? Получили строку — вставили строку в DOM. Парсит браузер. Быстрее и проще.

  1. 2. Вставить сообщение об ошибке в DOM (div id="error").

А откуда div’то возьмется? DOM ещё генерировать нужно или собирать из строки, что никак не отличается от серверного рендеринга, только теперь код разбит на две стороны.

  1. В итоге не теряем на рендере, на пересылке кода формы (существенно для мобильных)

Сколько там список ошибок занимает, байт 500? А сколько баннеров и прочей социальной лабуды на страницах, мегабайта два? На спичках экономите.

Не в сети

#10 23.06.2017 18:05:05

Re: Blade, отрисовать (получить Html разметку) только одну секцию

@Proger_XP, судя по всему вы вообще не поняли о чём я писал.

// Мой вариант
if (ошибка) {
   return response()->json([...]); // или просто return ['errormsg'=>'Ошибка'];
}
// Вариант топикстартера
if (ошибка) {
   $html = view('name', $data)->render(); // Тут теряем время
   return $html;
}

В случае с пересылкой - пересылается не форма или обычная страница, а маленький json.

Парсить ответ нужно в случае, если приходит страница - на ней нужно найти блок с контентом ($(response).find('div.content')) и только потом его вставить в DOM.

А откуда div’то возьмется?

Изначально есть в форме. См. пост. Просто нужно добавить ему идентификатор или класс. Хотя не обязательно.

Не в сети

#11 23.06.2017 19:23:35

Re: Blade, отрисовать (получить Html разметку) только одну секцию

Во-первых вставляя просто HTML Разметку, данный вставщик будет минимум кода и он может быть универсальным для многих страниц, т.е. без изменения кода вообще, а там где

div id="error"

надо прописывать эти id

+ мы можем возвращать не ошибки, а на оборот сообщение об успехе, типа регистрация прошла успешно.

Во вторых

$html = view('name', $data)->render(); // Тут теряем время

и много времени теряем?

У каждого свой подход, мне ближе минимизация работы с JS (не отказ и не в ущерб приложению) и больше работы с РНР, по мне он куда надежнее и предсказуем чем JS.


Изучаю Laravel, до этого дела с фреймворками не имел.
Печальные познания в английском.

Не в сети

#12 23.06.2017 20:31:43

Re: Blade, отрисовать (получить Html разметку) только одну секцию

  1. @Proger_XP, судя по всему вы вообще не поняли о чём я писал.

Я именно об этом и писал.

  1. В случае с пересылкой — пересылается не форма или обычная страница, а маленький json.

Возьмите полный размер вашей типичной страницы со всеми внешними скриптами включая трекеры, которые загружаются (или запрашиваются) при каждой загрузке страницы клиентом. Затем возьмите размер HTML и размер JSON при ошибках в форме (случай, который по определению возникает не всегда). И посмотрите, сколько % вы экономите в случае с JSON.

Кроме того, не забудьте, что сжатие страниц нивелирует и эту разницу.

А вот 5-10 внешних доменов (addthis, vk, tw, fb, metrika, adwords, …) это 5-10 handshake’ов по 50-500 мс каждый (пусть и параллельно) + процессорное время. Если это не проблема — то смешно говорить о каких-то экономиях на передаче JSON. Зато часть серверной логики по отрисовки оказывается дублированной на стороне клиента.

  1. $html = view(’name’, $data)->render(); // Тут теряем время
  2. и много времени теряем?

С точки зрения производительности нужно как можно больше кода выносить на клиент, так как клиентов много, а сервер один. Если приходит 1000 одновременных запросов, то если у вас SPA (страница целиком на JS) и сервер отдаёт только сырые данные, а клиенты каждый сами выстраивают страницу — это здорово разгружает сервер, т.к. он выполняет только половину работы на каждого клиента. С серверным рендерингом будет 1000 циклов отрисовки в дополнение к получению данных.

Здесь всё верно.

Другое дело, что такой подход для PHP не особо нативен и потому не очень удобен. Node.js — да, отлично подходит под такой сценарий. у вас шаблоны на JS, код на сервере на JS, на клиенте тоже, разумеется, JS, поэтому код на клиенте использует часть «серверного» кода. Дублирования мало.

А на PHP как ни крути обработка своя, на JS своя. Хорошо если получится шаблоны как-то совместить, но обычно имеется 2 набора шаблонов, 2 набора логики для отрисовки, необходимость как-то подтягивать данные типа языковых строк с сервера (привет, window.language = {...}) и т.д.

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

По своему опыту могу сказать, что когда проект упирается в железные ограничения, то обычно проще и надёжнее отмасштабировать новым железом (в добавок получаем резервирование — 2 сервера имеют меньше шансов упасть вместе). Так что быстрая разработка имеет больший приоритет.

Не в сети

#13 23.06.2017 21:50:43

Re: Blade, отрисовать (получить Html разметку) только одну секцию

@Proger_XP Я тоже загружаю отрендеренную на сервере форму, но только при первичной загрузке. У меня все модальные диалоги редактирования грузятся с сервера. Даже при добавлении новой записи я гружу пустой диалог с сервера. Но я не понимаю, зачем гнать целый диалог с сервера при ошибке валидации, когда пользователь внес некорректные данные и нажал кнопку Сохранить. Достаточно вернуть сообщение об ошибке. В общем, я никого не уговариваю. Нравится такой подход, ради бога. Мне проще передать просто ошибку и её отрисовать, чем перерисовывать весь диалог и переинициализировать плагины полей.

Не в сети

Подвал раздела