Trong Laravel, cách tốt nhất để chuyển các loại thông báo flash khác nhau trong phiên


115

Tôi đang tạo ứng dụng đầu tiên của mình trong Laravel và đang cố gắng tìm hiểu các thông báo flash phiên. Theo như tôi biết trong hành động của bộ điều khiển, tôi có thể đặt thông báo flash bằng cách

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

Đối với trường hợp chuyển hướng sang một tuyến đường khác, hoặc

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

Trong mẫu cốt vợt chính của mình, tôi sẽ có:

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

Như bạn có thể đã nhận thấy tôi đang sử dụng Bootstrap 3 trong ứng dụng của tôi và muốn tận dụng các lớp thông điệp khác nhau: alert-info, alert-warning, alert-danger, vv

Giả sử rằng trong bộ điều khiển của tôi, tôi biết loại thông báo tôi đang cài đặt, cách tốt nhất để chuyển và hiển thị nó trong chế độ xem là gì? Tôi có nên đặt một thông báo riêng trong phiên cho từng loại (ví dụ Session::flash('message_danger', 'This is a nasty message! Something's wrong.');) không? Sau đó, tôi cần một câu lệnh if riêng cho từng thông báo trong mẫu lưỡi dao của mình.

Bất kỳ lời khuyên nào được đánh giá cao.


itolutionstuff.com/post/… rất hữu ích cho tôi.
Ryan

Câu trả lời:


192

Một giải pháp là đưa hai biến vào phiên làm việc:

  1. Chính thông điệp
  2. "Lớp" cảnh báo của bạn

ví dụ:

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

Sau đó, theo quan điểm của bạn:

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

Lưu ý rằng tôi đã đặt một giá trị mặc định vào Session::get(). theo cách đó, bạn chỉ cần ghi đè nó nếu cảnh báo phải là một cái gì đó khác với alert-infolớp.

(đó là một ví dụ nhanh và chưa được kiểm tra :))


3
Thật thú vị, tôi không biết về thông số mặc định cho Session::get() Điều đó sẽ rất tiện dụng.
Nick Coad

1
Giống như hầu hết các giải pháp tin nhắn flash, điều này chỉ xử lý một tin nhắn. Vì vậy, thông thường, cần phải có một loạt các thông báo, mỗi thông báo có thể có một mức độ nghiêm trọng khác nhau và hiển thị tất cả chúng.
Jason

2
Dưới đây là những gì chúng ta đang sử dụng trong các dự án của chúng tôi gist.github.com/YavorK/7aa6e839dbe93e8854e4b033e31836a4
Hop hop

1
Điều này rất phản tác dụng ... Tại sao mọi người lại ủng hộ điều này?
Goowik

14
@Goowik - Nói rằng nó phản hiệu quả trong khi không đưa ra giải pháp hiệu quả hơn là phản hiệu quả.
SupaMonkey

49

Theo quan điểm của bạn:

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

Sau đó đặt thông báo flash trong bộ điều khiển:

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

35

Cách của tôi là luôn Redirect :: back () hoặc 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.');

Tôi có một chức năng trợ giúp để làm cho nó hoạt động cho tôi, thường thì chức năng này nằm trong một dịch vụ riêng biệt:

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

Và trong cách nhìn hoặc bố cục của tôi, tôi chỉ làm

{{ displayAlert() }}

4
Điều này chỉ đơn giản là tuyệt vời nhưng điều này hoạt động như thế nào$type = $type == 'error' : 'danger';
tràn vào

1
Bạn đặt người trợ giúp của mình ở đâu trong Lớp người trợ giúp riêng biệt?
utdev

16

Bạn có thể tạo nhiều tin nhắn với nhiều kiểu khác nhau. Hãy làm theo các bước sau:

  1. Tạo tệp: " 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. Trên bộ điều khiển cơ sở của bạn " 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;
}

Điều này sẽ làm cho FlashMessagesđặc điểm có sẵn cho tất cả các bộ điều khiển mở rộng lớp này.

  1. Tạo một mẫu lưỡi cho tin nhắn của chúng tôi: " 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. Trên " boot()" phương thức của " 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);
      });
    }

    ...
}

Điều này sẽ làm cho $messagesbiến có sẵn cho views/partials/message.blade.phpmẫu "" bất cứ khi nào nó được gọi.

  1. Trên mẫu của bạn, hãy bao gồm mẫu tin nhắn của chúng tôi - " 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>

Bạn chỉ cần đưa mẫu thông báo vào bất cứ nơi nào bạn muốn để hiển thị thông báo trên trang của mình.

  1. Trên bộ điều khiển của bạn, bạn có thể chỉ cần thực hiện việc này để đẩy các thông báo 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.');
  }

  ...

Hy vọng nó sẽ giúp bạn.


13

Chỉ cần quay lại với 'cờ' mà bạn muốn được xử lý mà không cần sử dụng bất kỳ chức năng người dùng bổ sung nào. Bộ điều khiển:

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

Lưu ý rằng tôi đã sử dụng cờ 'Thành công'.

Chế độ xem:

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

Vâng, nó thực sự hoạt động!


Bạn có rất nhiều lỗi chính tả trong câu trả lời của mình, nhưng cách tiếp cận của bạn rất hiệu quả.
Bat Lanyard

6

Một giải pháp khác là tạo lớp trợ giúp Cách tạo lớp trợ giúp tại đây

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

Sau đó, bạn có thể làm điều này.

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

hoặc là

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

và trong tầm nhìn của bạn

@if(Session::has('message'))
    {{Session::get('message')}}
@endif

5
Tôi không biết liệu tôi có đề xuất phương pháp này không vì nó đưa HTML ra khỏi chế độ xem và chuyển thành mã.
Nick Coad

5

Không phải là một fan hâm mộ lớn của các giải pháp được cung cấp (ví dụ: nhiều biến, các lớp trợ giúp, lặp qua 'các biến có thể hiện có'). Dưới đây là một giải pháp thay vì sử dụng một mảng thay vì hai biến riêng biệt. Nó cũng có thể dễ dàng mở rộng để xử lý nhiều lỗi nếu bạn muốn nhưng để đơn giản, tôi đã giữ nó trong một thông báo flash:

Chuyển hướng với mảng tin nhắn flash :

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

Đầu ra dựa trên nội dung mảng:

@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

Không liên quan vì bạn có thể có phương thức / plugin thông báo của riêng mình - nhưng chỉ để rõ ràng - bootstrapNotify chỉ để bắt đầu bootstrap-thông báo từ 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

Đối với ứng dụng của tôi, tôi đã tạo một chức năng trợ giúp:

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

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

bố trí tin nhắn, 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

và nhập mọi nơi để hiển thị thông báo:

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

3

Tôi thường làm điều này

trong hàm store () của tôi, tôi đặt cảnh báo thành công khi nó được lưu đúng cách.

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

trong hàm tiêu diệt () của tôi, tôi muốn tô màu cảnh báo màu đỏ để thông báo rằng nó đã bị xóa

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

Lưu ý, chúng tôi tạo hai cảnh báo với các tên flash khác nhau.

Và theo quan điểm của tôi, tôi sẽ thêm tin vào thời điểm thích hợp, cảnh báo cụ thể sẽ được gọi

@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

Tại đây bạn có thể tìm thấy các chuỗi tin nhắn flash khác nhau Tin nhắn flash trong Laravel 5


3

Bạn có thể sử dụng Macro Laravel.

Bạn có thể tạo macros.php trong app/helpersvà bao gồm nó routes.php.

nếu bạn muốn đặt macro của mình trong một tệp lớp thay vào đó, bạn có thể xem hướng dẫn này: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service- các nhà cung cấp

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

Trong bộ điều khiển của bạn:

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

Trong chế độ xem của bạn

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

3

Tôi nghĩ rằng cách sau sẽ hoạt động tốt với dòng mã ít hơn.

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

Tôi đang sử dụng một gói máy nướng bánh mì, nhưng bạn có thể có một cái gì đó như thế này trong tầm nhìn của bạn.

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

2

Trong bộ điều khiển:

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

Hoặc là

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

trong Blade hiển thị thông báo trong Blade As ur Des mong muốn Pattern:

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

Làm thế nào bạn vượt qua className?
chủ COTIGA

1

Chỉ gửi một mảng trong phiên thay vì một chuỗi, như thế này:

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

Nếu bạn muốn sử dụng Bootstrap Alert để làm cho chế độ xem của bạn tương tác hơn. Bạn có thể làm điều gì đó như sau:

Trong chức năng của bạn: -

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

Theo quan điểm của bạn: -

@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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.