У Laravel найкращий спосіб передавати різні види флеш-повідомлень у сеанс


115

Я роблю свою першу програму в Laravel і намагаюся обернути голову навколо флеш-повідомлень сесії. Наскільки я обізнаний у своїх діях контролера, я можу встановити спалаху, будь-ласка, перейшовши

Redirect::to('users/login')->with('message', 'Thanks for registering!'); //is this actually OK?

У разі переадресації на інший маршрут, або

Session::flash('message', 'This is a message!'); 

У моєму шаблоні головного леза я тоді мав би:

@if(Session::has('message'))
<p class="alert alert-info">{{ Session::get('message') }}</p>
@endif

Як ви вже помітили , я використовую Bootstrap 3 в моєму додатку і хотів би використовувати з різних класів повідомлень: alert-info, alert-warning, і alert-dangerт.д.

Якщо припустити, що в своєму контролері я знаю, який тип повідомлення я встановлюю, який найкращий спосіб передати та відобразити його у поданні? Чи слід встановити окреме повідомлення в сеансі для кожного типу (наприклад Session::flash('message_danger', 'This is a nasty message! Something's wrong.');)? Тоді мені знадобиться окремий if висловлювання для кожного повідомлення в шаблоні мого леза.

Будь-яка рада оцінена.


itsolutionstuff.com/post/… був для мене корисним.
Райан

Відповіді:


192

Одним з рішень було б прошивання двох змінних у сеанс:

  1. Само повідомлення
  2. "Клас" вашого сповіщення

наприклад:

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клас.

(це швидкий приклад і неперевірений :))


3
Цікаво, що я не знав про параметр за замовчуванням для Session::get() Це буде дуже зручно.
Нік Коуд

1
Як і більшість флеш-рішень, це стосується лише одного повідомлення. Тому часто потрібно мати можливість звільнити купу повідомлень, кожне може бути різної суворості, і відобразити їх усі.
Джейсон

2
Ось що ми використовуємо в наших проектах gist.github.com/YavorK/7aa6e839dbe93e8854e4b033e31836a4
Hop hop

1
Це настільки протилежне продуктивності ... Чому всі виступають за це?
Goowik

14
@Goowik - Сказати, що його лічильник продуктивний, не пропонуючи більш продуктивного рішення, є протипродуктивним.
SupaMonkey

49

На ваш погляд:

<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');

35

Мій шлях - завжди перенаправляти :: назад () або перенаправляти :: на ():

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() }}

4
Це просто приголомшливо, але як це працює$type = $type == 'error' : 'danger';
перелийте

1
Куди ви помістите свого помічника в окремий клас помічників?
utdev

16

Ви можете робити кілька повідомлень і різних типів. Виконайте наступні кроки нижче:

  1. Створіть файл: " 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);
  }
}
  1. На базовому контролері " 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ознаку доступною для всіх контролерів, що розширюють цей клас.

  1. Створіть шаблон леза для наших повідомлень: " 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
  1. Про " 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шаблону " " кожного разу, коли вона викликається.

  1. У своєму шаблоні включіть наш шаблон повідомлень - " 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>

Вам потрібно лише включити шаблон повідомлень там, де ви хочете відобразити повідомлення на своїй сторінці.

  1. На контролері ви можете просто зробити це для натискання флеш-повідомлень:
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.');
  }

  ...

Сподіваюся, це допоможе тобі.


13

Просто поверніть «прапор», який потрібно обробляти, не використовуючи жодної додаткової функції користувача. Контролер:

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

Так, це справді працює!


У вашій відповіді є помилка друку, але ваш підхід чудово працює.
Бат-шнур

6

Іншим рішенням буде створення класу помічників. Як створити класи помічників тут

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

5
Я не знаю, чи рекомендував би я такий підхід, оскільки він знімає HTML з виду та коду.
Нік Коуд

5

Не великий фанат запропонованих рішень (тобто: декілька змінних, допоміжні класи, перебирання через "можливо існуючі змінні"). Нижче наведено рішення, яке натомість використовує масив на відміну від двох окремих змінних. Це також легко розширюється для обробки декількох помилок, якщо ви хочете, але для простоти, я зберіг це одне спалахне повідомлення:

Перенаправлення з масивом флеш-повідомлень :

    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-сповіщення від 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"}});
}

4

Для моєї програми я зробив функцію помічника:

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'),
])

3

Я зазвичай роблю це

у своїй функції store () я надсилаю сповіщення про успіх, як тільки воно зберігається належним чином.

\Session::flash('flash_message','Office successfully updated.');

у своїй функції знищення () я хотів пофарбувати попереджувальний червоний колір, щоб повідомити, що його видалено

\Session::flash('flash_message_delete','Office successfully deleted.');

Зауважте, ми створюємо два попередження з різними іменами спалаху.

І на мою думку, я додам умову, коли в потрібний час буде зателефоновано конкретне попередження

@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

Тут ви можете знайти різні флеш-повідомлення Flash Flash Messages у Laravel 5


3

Ви можете використовувати макроси Laravel.

Ви можете створити macros.php вapp/helpers і включити його routes.php.

якщо ви хочете замість цього помістити макроси у файл класу, ви можете переглянути цей підручник: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service- постачальник

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">&times;</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

3

Я думаю, що наступне було б добре працювати з меншою лінією кодів.

        session()->flash('toast', [
        'status' => 'success', 
        'body' => 'Body',
        'topic' => 'Success']
    );

Я використовую тостер, але ви можете мати щось подібне на ваш погляд.

             toastr.{{session('toast.status')}}(
              '{{session('toast.body')}}', 
              '{{session('toast.topic')}}'
             );

2

У контролері:

Redirect::to('/path')->with('message', 'your message'); 

Або

Session::flash('message', 'your message'); 

в Блейд-шоу повідомлення в Блейді як бажаний шаблон:

@if(Session::has('message'))
    <div class="alert alert-className">
        {{session('message')}}
    </div>
@endif

Як ви передаєте className?
Бос COTIGA

1

Просто надішліть масив у сеанс, а не рядок, як це:

Session::flash('message', ['text'=>'this is a danger message','type'=>'danger']);

@if(Session::has('message'))
    <div class="alert alert-{{session('message')['type']}}">
        {{session('message')['text']}}
    </div>
@endif


0

Якщо ви хочете використовувати сповіщення Bootstrap, щоб зробити ваш погляд більш інтерактивним. Ви можете зробити щось подібне:

У вашій функції: -

if($author->save()){
    Session::flash('message', 'Author has been successfully added');
    Session::flash('class', 'success'); //you can replace success by [info,warning,danger]
    return redirect('main/successlogin');

У ваших поглядах: -

@if(Session::has('message'))
    <div class="alert alert-{{Session::get('class')}} alert-dismissible fade show w-50 ml-auto alert-custom"
        role="alert">
        {{ Session::get('message') }}
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
@endif
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.