Di Laravel, cara terbaik untuk menyampaikan berbagai jenis pesan flash dalam sesi tersebut

115

Saya membuat aplikasi pertama saya di Laravel dan mencoba memahami pesan flash sesi. Sejauh yang saya ketahui dalam tindakan pengontrol saya, saya dapat mengatur pesan flash baik dengan pergi

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

Untuk kasus pengalihan ke rute lain, atau

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

Dalam template master blade saya, saya akan memiliki:

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

Seperti Anda mungkin telah memperhatikan Saya menggunakan Bootstrap 3 di app saya dan ingin memanfaatkan kelas pesan yang berbeda: alert-info, alert-warning, alert-dangerdll

Dengan asumsi bahwa di pengontrol saya, saya tahu jenis pesan apa yang saya setel, apa cara terbaik untuk meneruskan dan menampilkannya dalam tampilan? Haruskah saya menetapkan pesan terpisah dalam sesi untuk setiap jenis (misalnya Session::flash('message_danger', 'This is a nasty message! Something's wrong.');)? Maka saya memerlukan pernyataan if terpisah untuk setiap pesan di template blade saya.

Setiap saran dihargai.

harryg
sumber
itsolutionstuff.com/post/… sangat membantu saya.
Ryan

Jawaban:

192

Salah satu solusinya adalah mem-flash dua variabel ke dalam sesi:

  1. Pesan itu sendiri
  2. "Kelas" notifikasi Anda

sebagai contoh:

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

Kemudian dalam pandangan Anda:

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

Catatan Saya telah memasukkan nilai default ke file Session::get(). dengan cara itu Anda hanya perlu menggantinya jika peringatan harus berupa sesuatu selain alert-infokelas.

(itu adalah contoh singkat, dan belum teruji :))

msturdy
sumber
3
Menarik, saya tidak tahu tentang parameter default untuk Session::get() Itu akan sangat berguna.
Nick Coad
1
Seperti kebanyakan solusi pesan flash, ini hanya berhubungan dengan satu pesan. Seringkali, sangatlah penting untuk dapat mengeluarkan banyak pesan, masing-masing mungkin memiliki tingkat keparahan yang berbeda, dan menampilkan semuanya.
Jason
2
Inilah yang kami gunakan dalam proyek kami gist.github.com/YavorK/7aa6e839dbe93e8854e4b033e31836a4
Hop hop
1
Ini sangat kontra produktif ... Mengapa semua orang mendukung ini?
Goowik
14
@Goowik - Mengatakan kontra produktif sementara tidak menawarkan solusi yang lebih produktif adalah kontra produktif.
SupaMonkey
49

Dalam pandangan Anda:

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

Kemudian atur pesan flash di pengontrol:

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

Cara saya adalah selalu Redirect :: back () atau 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.');

Saya memiliki fungsi pembantu untuk membuatnya berfungsi untuk saya, biasanya ini ada dalam layanan terpisah:

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

Dan dalam tampilan atau tata letak saya, saya hanya melakukannya

{{ displayAlert() }}
Antonio Carlos Ribeiro
sumber
4
Ini luar biasa, tetapi bagaimana cara kerjanya$type = $type == 'error' : 'danger';
overflow
1
Di mana Anda menempatkan pembantu Anda di Kelas Penolong yang terpisah?
utdev
16

Anda dapat membuat banyak pesan dan dengan jenis yang berbeda. Ikuti langkah-langkah berikut ini:

  1. Buat file: " 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. Pada pengontrol dasar Anda " 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;
}

Ini akan membuat FlashMessagessifat tersedia untuk semua pengontrol yang memperluas kelas ini.

  1. Buat template blade untuk pesan kita: " 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. Pada " boot()" metode " 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);
      });
    }

    ...
}

Ini akan membuat $messagesvariabel tersedia untuk views/partials/message.blade.phptemplate " " setiap kali dipanggil.

  1. Pada template Anda, sertakan template pesan kami - " 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>

Anda hanya perlu menyertakan template pesan di mana pun Anda ingin menampilkan pesan di halaman Anda.

  1. Pada pengontrol Anda, Anda cukup melakukan ini untuk mendorong pesan flash:
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.');
  }

  ...

Semoga bisa membantu Anda.

clemquinones
sumber
13

Cukup kembalikan dengan 'bendera' yang ingin Anda perlakukan tanpa menggunakan fungsi pengguna tambahan. Pengendali:

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

Perhatikan bahwa saya menggunakan tanda 'Sukses'.

Pandangan:

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

Ya, ini benar-benar berhasil!

Richelly Italo
sumber
Anda memiliki banyak kesalahan ketik dalam jawaban Anda, tetapi pendekatan Anda berfungsi dengan baik.
Bat Lanyard
6

Solusi lain adalah membuat kelas pembantu. Cara Membuat kelas pembantu di sini

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

Maka Anda bisa melakukan ini.

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

atau

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

dan menurut pandanganmu

@if(Session::has('message'))
    {{Session::get('message')}}
@endif
Ayobami Opeyemi
sumber
5
Saya tidak tahu apakah saya akan merekomendasikan pendekatan ini karena mengambil HTML dari tampilan dan menjadi kode.
Nick Coad
5

Bukan penggemar berat solusi yang disediakan (yaitu: banyak variabel, kelas pembantu, perulangan melalui 'variabel yang mungkin ada'). Di bawah ini adalah solusi yang menggunakan array sebagai lawan dari dua variabel terpisah. Ini juga dapat dengan mudah diperpanjang untuk menangani beberapa kesalahan jika Anda inginkan tetapi untuk kesederhanaan, saya menyimpannya ke satu pesan kilat:

Redirect dengan larik pesan flash :

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

Output berdasarkan konten array:

@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

Tidak terkait karena Anda mungkin memiliki metode / plugin notifikasi Anda sendiri - tetapi hanya untuk kejelasan - bootstrapNotify hanya untuk memulai bootstrap-notify dari 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
sumber
4

Untuk aplikasi saya, saya membuat fungsi pembantu:

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

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

tata letak pesan, 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

dan impor setiap tempat untuk menampilkan pesan:

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

Saya biasanya melakukan ini

di fungsi store () saya, saya memberi peringatan sukses setelah disimpan dengan benar.

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

dalam fungsi destroy () saya, saya ingin memberi warna merah peringatan untuk memberi tahu bahwa itu dihapus

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

Perhatikan, kami membuat dua peringatan dengan nama flash berbeda.

Dan dalam pandangan saya, saya akan menambahkan ketentuan kapan waktu yang tepat peringatan tertentu akan dipanggil

@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

Di sini Anda dapat menemukan pesan flash yang berbeda stlyes Pesan Flash di Laravel 5

Ikong
sumber
3

Anda bisa menggunakan Laravel Macros.

Anda dapat membuat macros.php dalamapp/helpers dan memasukkannya routes.php.

jika Anda ingin meletakkan makro Anda dalam file kelas, Anda dapat melihat tutorial ini: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service- pemberi

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

Di pengontrol Anda:

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

Dalam Pandangan Anda

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

Saya pikir berikut ini akan bekerja dengan baik dengan baris kode yang lebih sedikit.

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

Saya menggunakan paket pemanggang roti, tetapi Anda dapat melihat sesuatu seperti ini dalam pandangan Anda.

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

Dalam Pengontrol:

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

Atau

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

di Blade show pesan di Blade As ur Desired Pattern:

@if(Session::has('message'))
    <div class="alert alert-className">
        {{session('message')}}
    </div>
@endif
PraKash
sumber
Bagaimana Anda lulus className?
Bos COTIGA
1

Kirimkan saja sebuah array dalam sesi daripada sebuah string, seperti ini:

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
shamaseen
sumber
0

Saya menemukan cara yang elegan untuk mem-flash pesan. Itu dibuat oleh Jeffrey Way dari Laracast. periksa ... https://github.com/laracasts/flash

Johan H.
sumber
0

Jika Anda ingin menggunakan Peringatan Bootstrap untuk membuat tampilan Anda lebih interaktif. Anda bisa melakukan sesuatu seperti ini:

Dalam fungsi Anda: -

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

Dalam pandangan Anda: -

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