In Laravel der beste Weg, um verschiedene Arten von Flash-Nachrichten in der Sitzung zu übergeben

115

Ich mache meine erste App in Laravel und versuche, mich mit den Flash-Nachrichten der Sitzung vertraut zu machen. Soweit mir in meiner Controller-Aktion bekannt ist, kann ich entweder eine Flash-Nachricht setzen, indem ich gehe

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

Für den Fall der Umleitung auf eine andere Route oder

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

In meiner Master Blade-Vorlage hätte ich dann:

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

Wie Sie mir Bootstrap haben bemerkt , können 3 in meiner app bin mit und möchte Verwendung der verschiedenen Nachrichtenklassen machen: alert-info, alert-warning,alert-danger usw.

Angenommen, ich weiß in meinem Controller, welche Art von Nachricht ich einstelle, wie kann ich sie am besten übergeben und in der Ansicht anzeigen? Sollte ich in der Sitzung für jeden Typ eine eigene Nachricht festlegen (zSession::flash('message_danger', 'This is a nasty message! Something's wrong.'); )? Dann benötige ich für jede Nachricht in meiner Blade-Vorlage eine separate if-Anweisung.

Jeder Rat geschätzt.

Harryg
quelle
itsolutionstuff.com/post/… war hilfreich für mich.
Ryan

Antworten:

192

Eine Lösung wäre, zwei Variablen in die Sitzung zu flashen:

  1. Die Nachricht selbst
  2. Die "Klasse" Ihrer Warnung

beispielsweise:

Session::flash('message', 'This is a message!'); 
Session::flash('alert-class', 'alert-danger'); 

Dann aus Ihrer Sicht:

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

Hinweis Ich habe einen Standardwert in die eingegebenSession::get() . Auf diese Weise müssen Sie es nur überschreiben, wenn die Warnung etwas anderes als die alert-infoKlasse sein soll.

(das ist ein kurzes Beispiel und ungetestet :))

msturdy
quelle
3
Interessant, ich wusste nicht über den Standardparameter für Session::get() Das wird sehr praktisch sein.
Nick Coad
1
Wie bei den meisten Flash-Nachrichtenlösungen wird nur eine Nachricht behandelt. So oft ist es notwendig, eine Reihe von Nachrichten mit jeweils unterschiedlichem Schweregrad abzufeuern und alle anzeigen zu lassen.
Jason
2
Hier ist, was wir in unseren Projekten verwenden: gist.github.com/YavorK/7aa6e839dbe93e8854e4b033e31836a4
Hop Hop
1
Das ist so kontraproduktiv ... Warum stimmen alle dafür?
Goowik
14
@Goowik - Es ist kontraproduktiv zu sagen, dass es kontraproduktiv ist, ohne eine produktivere Lösung anzubieten.
SupaMonkey
49

Aus Ihrer Sicht:

<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>

Stellen Sie dann eine Flash-Meldung in der Steuerung ein:

Session::flash('alert-danger', 'danger');
Session::flash('alert-warning', 'warning');
Session::flash('alert-success', 'success');
Session::flash('alert-info', 'info');
danelips
quelle
35

Mein Weg ist immer Redirect :: back () oder Redirect :: to ():

Redirect::back()->with('message', 'error|There was an error...');

Redirect::back()->with('message', 'message|Record updated.');

Redirect::to('/')->with('message', 'success|Record updated.');

Ich habe eine Hilfsfunktion, damit es für mich funktioniert. Normalerweise befindet sich diese in einem separaten Dienst:

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

Und aus meiner Sicht oder meinem Layout mache ich es einfach

{{ displayAlert() }}
Antonio Carlos Ribeiro
quelle
4
Das ist einfach fantastisch, aber wie funktioniert das$type = $type == 'error' : 'danger';
Überlauf
1
Wo setzen Sie Ihren Helfer in eine separate Helferklasse ein?
utdev
16

Sie können mehrere Nachrichten mit unterschiedlichen Typen erstellen. Befolgen Sie diese Schritte unten:

  1. Erstellen Sie eine Datei: " 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. Auf Ihrem Basis-Controller " 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;
}

Dadurch wird das FlashMessagesMerkmal allen Controllern zur Verfügung gestellt, die diese Klasse erweitern.

  1. Erstellen Sie eine Blade-Vorlage für unsere Nachrichten: " 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. Auf " boot()" Methode von " 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);
      });
    }

    ...
}

Dadurch wird die $messagesVariable bei views/partials/message.blade.phpjedem Aufruf der Vorlage " " zur Verfügung gestellt .

  1. Fügen Sie Ihrer Vorlage unsere Nachrichtenvorlage hinzu - " 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>

Sie müssen die Nachrichtenvorlage nur dort einfügen, wo Sie die Nachrichten auf Ihrer Seite anzeigen möchten.

  1. Auf Ihrem Controller können Sie dies einfach tun, um Flash-Nachrichten zu senden:
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.');
  }

  ...

Hoffe es wird dir helfen.

Clemchinone
quelle
12

Kehren Sie einfach mit dem 'Flag' zurück, das Sie behandeln möchten, ohne eine zusätzliche Benutzerfunktion zu verwenden. Der Controller:

return \Redirect::back()->withSuccess( 'Message you want show in View' );

Beachten Sie, dass ich das Flag 'Erfolg' verwendet habe.

Die Aussicht:

@if( Session::has( 'success' ))
     {{ Session::get( 'success' ) }}
@elseif( Session::has( 'warning' ))
     {{ Session::get( 'warning' ) }} <!-- here to 'withWarning()' -->
@endif

Ja, es funktioniert wirklich!

Richelly Italo
quelle
Sie haben eine Menge Tippfehler in Ihrer Antwort, aber Ihr Ansatz funktioniert hervorragend.
Bat Lanyard
6

Eine andere Lösung wäre das Erstellen einer Hilfsklasse. So erstellen Sie hier Hilfsklassen

class Helper{
     public static function format_message($message,$type)
    {
         return '<p class="alert alert-'.$type.'">'.$message.'</p>'
    }
}

Dann können Sie dies tun.

Redirect::to('users/login')->with('message', Helper::format_message('A bla blah occured','error'));

oder

Redirect::to('users/login')->with('message', Helper::format_message('Thanks for registering!','info'));

und aus Ihrer Sicht

@if(Session::has('message'))
    {{Session::get('message')}}
@endif
Ayobami Opeyemi
quelle
5
Ich weiß nicht, ob ich diesen Ansatz empfehlen würde, da HTML aus der Ansicht in Code umgewandelt wird.
Nick Coad
5

Kein großer Fan der angebotenen Lösungen (dh: mehrere Variablen, Hilfsklassen, Schleifen durch "möglicherweise vorhandene Variablen"). Im Folgenden finden Sie eine Lösung, bei der stattdessen ein Array anstelle von zwei separaten Variablen verwendet wird. Es ist auch leicht erweiterbar, um mehrere Fehler zu behandeln, falls Sie dies wünschen. Der Einfachheit halber habe ich es auf eine Flash-Nachricht beschränkt:

Umlenken mit Flash - Mitteilung Array :

    return redirect('/admin/permissions')->with('flash_message', ['success','Updated Successfully','Permission "'. $permission->name .'" updated successfully!']);

Ausgabe basierend auf Array-Inhalt:

@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

Unabhängig davon, da Sie möglicherweise über eine eigene Benachrichtigungsmethode / ein eigenes Benachrichtigungs-Plugin verfügen - aber nur aus Gründen der Übersichtlichkeit - dient bootstrapNotify lediglich zum Starten der Bootstrap-Benachrichtigung von 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"}});
}
SupaMonkey
quelle
4

Für meine Anwendung habe ich eine Hilfsfunktion erstellt:

function message( $message , $status = 'success', $redirectPath = null )
{
     $redirectPath = $redirectPath == null ? back() : redirect( $redirectPath );

     return $redirectPath->with([
         'message'   =>  $message,
         'status'    =>  $status,
    ]);
}

Nachrichtenlayout , 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

und importiere jeden Ort, an dem die Nachricht angezeigt werden soll:

@include('main.layouts.message', [
    'status'    =>  session('status'),
    'message'   =>  session('message'),
])
ivahidmontazer
quelle
3

Normalerweise mache ich das

In meiner store () -Funktion setze ich eine Erfolgswarnung, sobald sie richtig gespeichert wurde.

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

In meiner Funktion destroy () wollte ich die Warnung rot färben, um zu benachrichtigen, dass sie gelöscht wurde

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

Beachten Sie, dass wir zwei Warnungen mit unterschiedlichen Flash-Namen erstellen.

Und meiner Ansicht nach werde ich die Bedingung hinzufügen, wann der richtige Alarm zum richtigen Zeitpunkt aufgerufen wird

@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

Hier finden Sie verschiedene Flash Message Stlyes Flash Messages in Laravel 5

Ikong
quelle
3

Sie könnten Laravel-Makros verwenden.

Sie können erstellen macros.php inapp/helpers routen.php und einschließen.

Wenn Sie Ihre Makros stattdessen in eine Klassendatei einfügen möchten, können Sie sich dieses Tutorial ansehen: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service- Anbieter

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

In Ihrem Controller:

Session::flash('message', 'This is so dangerous!'); 
Session::flash('alert', 'alert-danger');

In Ihrer Ansicht

@if(Session::has('message') && Session::has('alert') )
  {{HTML::alert($class=Session::get('alert'), $value=Session::get('message'), $show=true)}}
@endif
Emeka Mbah
quelle
3

Ich denke, dass das Folgende mit weniger Codezeilen gut funktionieren würde.

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

Ich verwende ein Toasterpaket, aber Sie können so etwas aus Ihrer Sicht haben.

             toastr.{{session('toast.status')}}(
              '{{session('toast.body')}}', 
              '{{session('toast.topic')}}'
             );
Segun Kess
quelle
2

Im Controller:

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

Oder

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

in Blade show message in Blade As ur Gewünschtes Muster:

@if(Session::has('message'))
    <div class="alert alert-className">
        {{session('message')}}
    </div>
@endif
PraKash
quelle
Wie übergeben Sie den Klassennamen?
Boss COTIGA
1

Senden Sie einfach ein Array in der Sitzung und nicht wie folgt:

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
Schamaseen
quelle
0

Ich bin auf diese elegante Art gestoßen, Nachrichten zu flashen. Es wurde von Jeffrey Way aus Laracast hergestellt. Probieren Sie es aus ... https://github.com/laracasts/flash

Johan H.
quelle
0

Wenn Sie Bootstrap Alert verwenden möchten, um Ihre Ansicht interaktiver zu gestalten. Sie können so etwas tun:

In Ihrer Funktion: -

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

In Ihren Ansichten: -

@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
Riwaj Chalise
quelle