В Laravel, лучший способ передать различные типы флэш-сообщений в сессии
Я делаю свое первое приложение в Laravel и пытаюсь получить мою голову вокруг сессии флэш-сообщений. Насколько я знаю, в моем действии контроллера я могу установить флэш-сообщение либо перейдя
Redirect::to('users/login')->with('message', 'Thanks for registering!'); //is this actually OK?
в случае перенаправления на другой маршрут, или
Session::flash('message', 'This is a message!');
в моем шаблоне master blade я бы тогда имел:
@if(Session::has('message'))
<p class="alert alert-info">{{ Session::get('message') }}</p>
@endif
как вы, возможно, заметили, я использую Bootstrap 3 в моем приложении и хотел бы использовать различные классы сообщений: alert-info
, alert-warning
,alert-danger
etc.
предполагая, что в моем контроллере я знаю, какой тип сообщения я устанавливаю, каков наилучший способ передать и отобразить его в представлении? Должен ли я установить отдельное сообщение в сеансе для каждого типа (например,Session::flash('message_danger', 'This is a nasty message! Something's wrong.');
)? Тогда мне понадобится отдельный оператор if для каждого сообщения в моем шаблоне blade.
любые советы с благодарностью.
11 ответов:
одним из решений было бы прошить две переменные в сеанс:
- сообщении
- "класс" вашего оповещения
например:
Session::flash('message', 'This is a message!'); Session::flash('alert-class', 'alert-danger');
тогда на ваш взгляд:
@if(Session::has('message')) <p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p> @endif
обратите внимание, что я поставил значение по умолчанию на
Session::get()
. таким образом, вам нужно только переопределить его, если предупреждение должно быть чем-то другим, чемalert-info
класса.(это маленький пример, и непроверенные :) )
на ваш взгляд:
<div class="flash-message"> @foreach (['danger', 'warning', 'success', 'info'] as $msg) @if(Session::has('alert-' . $msg)) <p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }}</p> @endif @endforeach </div>
затем установите флэш-сообщение в контроллере:
Session::flash('alert-danger', 'danger'); Session::flash('alert-warning', 'warning'); Session::flash('alert-success', 'success'); Session::flash('alert-info', 'info');
мой способ-всегда перенаправлять:: back () или перенаправлять::to ():
Redirect::back()->with('message', 'error|There was an error...'); Redirect::back()->with('message', 'message|Record updated.'); Redirect::to('/')->with('message', 'success|Record updated.');
у меня есть вспомогательная функция, чтобы заставить его работать для меня, обычно это в отдельную службу:
function displayAlert() { if (Session::has('message')) { list($type, $message) = explode('|', Session::get('message')); $type = $type == 'error' : 'danger'; $type = $type == 'message' : 'info'; return sprintf('<div class="alert alert-%s">%s</div>', $type, message); } return ''; }
и на мой взгляд или макет я просто делаю
{{ displayAlert() }}
просто вернитесь с "флагом", который вы хотите обработать, не используя никаких дополнительных пользовательских функций. Контроллер:
return \Redirect::back()->withSuccess( 'Message you want show in View' );
обратите внимание, что я использовал флаг "успех".
Вид:
@if( Session::has( 'success' )) {{ Session::get( 'success' ) }} @elseif( Session::has( 'warning' )) {{ Session::get( 'warning' ) }} <!-- here to 'withWarning()' --> @endif
Да, это действительно работает!
вы можете сделать несколько сообщений и с разными типами. Выполните следующие действия:
- создать файл: "
app/Components/FlashMessages.php
"namespace App\Components; trait FlashMessages { protected static function message($level = 'info', $message = null) { if (session()->has('messages')) { $messages = session()->pull('messages'); } $messages[] = $message = ['level' => $level, 'message' => $message]; session()->flash('messages', $messages); return $message; } protected static function messages() { return self::hasMessages() ? session()->pull('messages') : []; } protected static function hasMessages() { return session()->has('messages'); } protected static function success($message) { return self::message('success', $message); } protected static function info($message) { return self::message('info', $message); } protected static function warning($message) { return self::message('warning', $message); } protected static function danger($message) { return self::message('danger', $message); } }
- на базе контроллера "
app/Http/Controllers/Controller.php
".namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Routing\Controller as BaseController; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesResources; use App\Components\FlashMessages; class Controller extends BaseController { use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests; use FlashMessages; }
это
FlashMessages
черта доступна для всех контроллеров, которые расширяют этот класс.
- создать шаблон Блейда для наших сообщений: "
views/partials/messages.blade.php
"@if (count($messages)) <div class="row"> <div class="col-md-12"> @foreach ($messages as $message) <div class="alert alert-{{ $message['level'] }}">{!! $message['message'] !!}</div> @endforeach </div> </div> @endif
- On"
boot()
" метод "app/Providers/AppServiceProvider.php
":namespace App\Providers; use Illuminate\Support\ServiceProvider; use App\Components\FlashMessages; class AppServiceProvider extends ServiceProvider { use FlashMessages; public function boot() { view()->composer('partials.messages', function ($view) { $messages = self::messages(); return $view->with('messages', $messages); }); } ... }
это
$messages
переменной, доступной для "views/partials/message.blade.php
" шаблон всякий раз, когда он вызывается.
- на вашем шаблоне, включите наш шаблон сообщений -"
views/partials/messages.blade.php
"<div class="row"> <p>Page title goes here</p> </div> @include ('partials.messages') <div class="row"> <div class="col-md-12"> Page content goes here </div> </div>
вам нужно только включить шаблон сообщения, где вы хотите отобразить сообщения на Вашей странице.
- на ваш контроллер, вы можете просто сделать это, чтобы подтолкнуть сообщения:
use App\Components\FlashMessages; class ProductsController { use FlashMessages; public function store(Request $request) { self::message('info', 'Just a plain message.'); self::message('success', 'Item has been added.'); self::message('warning', 'Service is currently under maintenance.'); self::message('danger', 'An unknown error occured.'); //or self::info('Just a plain message.'); self::success('Item has been added.'); self::warning('Service is currently under maintenance.'); self::danger('An unknown error occured.'); } ...
надеюсь, что это поможет вам.
другим решением было бы создать вспомогательный класс как создать вспомогательные классы
class Helper{ public static function format_message($message,$type) { return '<p class="alert alert-'.$type.'">'.$message.'</p>' } }
затем вы можете сделать это.
Redirect::to('users/login')->with('message', Helper::format_message('A bla blah occured','error'));
или
Redirect::to('users/login')->with('message', Helper::format_message('Thanks for registering!','info'));
и в
@if(Session::has('message')) {{Session::get('message')}} @endif
для моего приложения, я сделал вспомогательную функцию:
function message( $message , $status = 'success', $redirectPath = null ) { $redirectPath = $redirectPath == null ? back() : redirect( $redirectPath ); return $redirectPath->with([ 'message' => $message, 'status' => $status, ]); }
макет сообщения,
main.layouts.message
:@if($status) <div class="center-block affix alert alert-{{$status}}"> <i class="fa fa-{{ $status == 'success' ? 'check' : $status}}"></i> <span> {{ $message }} </span> </div> @endif
и импортировать каждый, где показать сообщение:
@include('main.layouts.message', [ 'status' => session('status'), 'message' => session('message'), ])
Я обычно так делаю
в моей функции store () я поставил предупреждение об успехе, как только он был сохранен правильно.
\Session::flash('flash_message','Office successfully updated.');
в моей функции destroy () я хотел покрасить предупреждение красным цветом, чтобы уведомить, что его удалили
\Session::flash('flash_message_delete','Office successfully deleted.');
обратите внимание, мы создаем два предупреждения с разными именами flash.
и на мой взгляд, я добавлю условие, когда в нужное время будет вызвано конкретное предупреждение
@if(Session::has('flash_message')) <div class="alert alert-success"><span class="glyphicon glyphicon-ok"></span><em> {!! session('flash_message') !!}</em></div> @endif @if(Session::has('flash_message_delete')) <div class="alert alert-danger"><span class="glyphicon glyphicon-ok"></span><em> {!! session('flash_message_delete') !!}</em></div> @endif
здесь вы можете найти различные stlyes сообщение Флэш-сообщения в Laravel 5
вы можете использовать макросы Laravel.
вы можете создать
macros.php
наapp/helpers
и включить его в маршруты.РНР.если вы хотите поместить свои макросы в файл класса вместо этого, вы можете посмотреть этот учебник: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service-provider
HTML::macro('alert', function($class='alert-danger', $value="",$show=false) { $display = $show ? 'display:block' : 'display:none'; return '<div class="alert '.$class.'" style="'.$display.'"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <strong><i class="fa fa-times"></i></strong>'.$value.' </div>'; });
в вашем контроллере:
Session::flash('message', 'This is so dangerous!'); Session::flash('alert', 'alert-danger');
на ваш взгляд
@if(Session::has('message') && Session::has('alert') ) {{HTML::alert($class=Session::get('alert'), $value=Session::get('message'), $show=true)}} @endif
не большой поклонник предоставленных решений (т. е.: несколько переменных, вспомогательные классы, цикл через "возможно существующие переменные"). Ниже приведено решение, которое вместо этого использует массив, а не две отдельные переменные. Он также легко расширяется для обработки нескольких ошибок, если вы хотите, но для простоты я сохранил его до одного флэш-сообщения:
перенаправление с флэш-сообщением массив:
return redirect('/admin/permissions')->with('flash_message', ['success','Updated Successfully','Permission "'. $permission->name .'" updated successfully!']);
вывод на основе массива содержание:
@if(Session::has('flash_message')) <script type="text/javascript"> jQuery(document).ready(function(){ bootstrapNotify('{{session('flash_message')[0]}}','{{session('flash_message')[1]}}','{{session('flash_message')[2]}}'); }); </script> @endif
не связаны, так как у вас может быть свой собственный метод уведомления / плагин - но только для ясности-bootstrapNotify - это просто инициировать bootstrap-notify от http://bootstrap-notify.remabledesigns.com/:
function bootstrapNotify(type,title = 'Notification',message) { switch (type) { case 'success': icon = "la-check-circle"; break; case 'danger': icon = "la-times-circle"; break; case 'warning': icon = "la-exclamation-circle"; } $.notify({message: message, title : title, icon : "icon la "+ icon}, {type: type,allow_dismiss: true,newest_on_top: false,mouse_over: true,showProgressbar: false,spacing: 10,timer: 4000,placement: {from: "top",align: "right"},offset: {x: 30,y: 30},delay: 1000,z_index: 10000,animate: {enter: "animated bounce",exit: "animated fadeOut"}}); }