【问题标题】:In Laravel, the best way to pass different types of flash messages in the session在 Laravel 中,在 session 中传递不同类型的 flash 消息的最佳方式
【发布时间】:2014-01-27 01:33:09
【问题描述】:

我正在 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 语句。

任何建议表示赞赏。

【问题讨论】:

标签: session laravel laravel-4


【解决方案1】:

一种解决方案是将两个变量闪存到会话中:

  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

请注意,我已将 default value 放入 Session::get()。这样,您只需要在警告不是 alert-info 类的情况下覆盖它。

(这是一个简单的例子,未经测试:))

【讨论】:

  • 有趣,我不知道Session::get() 的默认参数,它会派上用场。
  • 像大多数 Flash 消息解决方案一样,这只处理一条消息。很多时候,有必要能够触发一堆消息,每条消息都可能具有不同的严重性,并将它们全部显示出来。
  • 这太适得其反了......为什么每个人都赞成这个?
  • @Goowik - 说它适得其反而不提供更高效的解决方案是适得其反的。
【解决方案2】:

另一种解决方案是创建一个辅助类 How to Create helper classes here

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

【讨论】:

  • 我不知道我是否会推荐这种方法,因为它会将 HTML 从视图中取出并放入代码中。
【解决方案3】:

我的方法是总是 Redirect::back() 或 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.');

我有一个辅助函数让它为我工作,通常这是在一个单独的服务中:

use Illuminate\Support\Facades\Session;

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

【讨论】:

  • 这简直太棒了,但这是如何工作的$type = $type == 'error' : 'danger';
  • 你把你的助手放在一个单独的助手类中的什么地方?
【解决方案4】:

在你看来:

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

【讨论】:

    【解决方案5】:

    你可以使用 Laravel 宏。

    您可以在app/helpers 中创建macros.php 并将其包含在routes.php 中。

    如果您希望将宏放在类文件中,可以查看本教程: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">&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
    

    【讨论】:

      【解决方案6】:

      只需返回您想要处理的“标志”,而无需使用任何额外的用户函数。 控制器:

      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
      

      是的,它确实有效!

      【讨论】:

      • 您的回答中有大量错别字,但您的方法效果很好。
      【解决方案7】:

      对于我的应用程序,我做了一个辅助函数:

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

      【讨论】:

        【解决方案8】:

        我通常这样做

        在我的 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
        

        在这里你可以找到不同的flash消息样式Flash Messages in Laravel 5

        【讨论】:

          【解决方案9】:

          您可以制作多条消息并使用不同的类型。 请按照以下步骤操作:

          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 trait 可用于所有扩展此类的控制器。

          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. 关于“app/Providers/AppServiceProvider.php”的“boot()”方法:
          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. 在您的控制器上,您可以简单地执行以下操作来推送 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.');
            }
          
            ...
          

          希望对你有帮助。

          【讨论】:

          • 不错。实际需要在 Laravel 中找到多条消息的解决方案。
          【解决方案10】:

          不太喜欢所提供的解决方案(即:多个变量、辅助类、循环通过“可能存在的变量”)。下面是一个解决方案,它使用数组而不是两个单独的变量。如果您愿意,它也可以轻松扩展以处理多个错误,但为简单起见,我将其保留为一条消息:

          使用 Flash 消息重定向数组:

              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 只是从 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"}});
          }
          

          【讨论】:

            【解决方案11】:

            我认为以下代码适用于较少的代码行。

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

            我使用的是烤面包机包,但您可以在视图中看到类似的东西。

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

            【讨论】:

              【解决方案12】:

              在控制器中:

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

              或者

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

              在 Blade 中显示消息中的 Blade As ur Desired Pattern:

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

              【讨论】:

              • 你如何传递类名?
              【解决方案13】:

              只需在会话中发送一个数组而不是一个字符串,如下所示:

              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
              

              【讨论】:

                【解决方案14】:

                我遇到了这种发送消息的优雅方式。它是由 Laracast 的 Jeffrey Way 制作的。 看看这个... https://github.com/laracasts/flash

                【讨论】:

                  【解决方案15】:

                  如果您想使用 Bootstrap Alert 使您的视图更具交互性。你可以这样做:

                  在你的函数中:-

                  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
                  

                  【讨论】:

                    【解决方案16】:

                    我喜欢最受好评的答案。 就我而言,我决定使用 session() 函数包装器,以避免在刀片模板中调用 facade。在控制器中也是如此。在我看来,它使代码更整洁。

                    线

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

                    变成

                    session()-&gt;flash('message', 'This is a message!');

                    在刀片模板中

                    session()-&gt;get('alert-class', 'alert-info');

                    干杯!

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2023-01-23
                      • 2016-08-03
                      • 2017-02-04
                      • 1970-01-01
                      • 2021-05-28
                      • 2015-11-17
                      相关资源
                      最近更新 更多