Yii2实现增删改查后留在当前页的方法详解

5年以前  |  阅读数:486 次  |  编程语言:PHP 

前言

实现增删改查操作成功后仍留在当前页,能给用户一个良好的体验。但是 Yii2 框架本身是没有在增删改查操作成功后仍留在当前页的效果的,要实现这样的一个效果得自己写。我的原则是不动核心代码,始终坚持自己的原则,现实现了我把它分享出来。殊途同归,如有更好的实现方法,欢迎交流。

需求分析

一、实现增删改查后操作成功后仍然留在当前页面。

1、链接的效果图

封装代码

共有两个文件ActionColumn.php和Helper.php1、ActionColumn.php文件


    <?php

    use Closure;
    use kartik\icons\Icon;
    use Yii;
    use yii\grid\Column;
    use yii\helpers\ArrayHelper;
    use yii\helpers\Html;
    use yii\helpers\Url;
    use common\components\Helper;

    /*
    *重写ActionColumn
     */
    class ActionColumn extends Column
    { 
     public $buttons;

     private $defaultButtons = [];

     private $callbackButtons;

     public $controller;

     public $urlCreator;

     public $url_append = '';

     public $appendReturnUrl = true; //默认为true,返回当前链接

     public function init()
     {
     parent::init();

     $this->defaultButtons = [
      [
      'url' => 'view',
      'icon' => 'eye',
      'class' => 'btn btn-success btn-xs',
      'label' => Yii::t('yii', 'View'),
      'appendReturnUrl' => false,
      'url_append' => '',
      'keyParam' => 'id',//是否传id,不传设置null
      ],
      [
      'url' => 'update',
      'icon' => 'pencil',
      'class' => 'btn btn-primary btn-xs',
      'label' => Yii::t('yii', 'Update'),
      ],
      [
      'url' => 'delete',
      'icon' => 'trash-o',
      'class' => 'btn btn-danger btn-xs',
      'label' => Yii::t('yii', 'Delete'),
      'options' => [
       'data-action' => 'delete',
      ],
      ]
     ];


     if (null === $this->buttons) {
      $this->buttons = $this->defaultButtons;
     } elseif ($this->buttons instanceof Closure) {
      $this->callbackButtons = $this->buttons;
     }
     }


     public function createUrl(
     $action,
     $model,
     $key,
     $index,
     $appendReturnUrl = null,
     $url_append = null,
     $keyParam = 'id',
     $attrs = []
     ) {
     if ($this->urlCreator instanceof Closure) {
      return call_user_func($this->urlCreator, $action, $model, $key, $index);
     } else {
      $params = [];
      if (is_array($key)) {
      $params = $key;
      } else {
      if (is_null($keyParam) === false) {
       $params = [$keyParam => (string)$key];
      }
      }
      $params[0] = $this->controller ? $this->controller . '/' . $action : $action;
      foreach ($attrs as $attrName) {
      if ($attrName === 'model') {
       $params['model'] = $model;
      } elseif ($attrName === 'mainCategory.category_group_id' && $model->getMainCategory()) {
       $params['category_group_id'] = $model->getMainCategory()->category_group_id;
      } else {
       $params[$attrName] = $model->getAttribute($attrName);
      }
      }
      if (is_null($appendReturnUrl) === true) {
      $appendReturnUrl = $this->appendReturnUrl;
      }
      if (is_null($url_append) === true) {
      $url_append = $this->url_append;
      }
      if ($appendReturnUrl) {
      $params['returnUrl'] = Helper::getReturnUrl();
      }
      return Url::toRoute($params) . $url_append;
     }
     }


     protected function renderDataCellContent($model, $key, $index)
     { 
     if ($this->callbackButtons instanceof Closure) {
      $btns = call_user_func($this->callbackButtons, $model, $key, $index, $this); 
      if (null === $btns) {
      $this->buttons = $this->defaultButtons;
      } else {
      $this->buttons = $btns;
      }
     }
     $min_width = count($this->buttons) * 34; //34 is button-width
     $data = Html::beginTag('div', ['class' => 'btn-group', 'style' => 'min-width: ' . $min_width . 'px']);
     foreach ($this->buttons as $button) {
      $appendReturnUrl = ArrayHelper::getValue($button, 'appendReturnUrl', $this->appendReturnUrl);
      $url_append = ArrayHelper::getValue($button, 'url_append', $this->url_append);
      $keyParam = ArrayHelper::getValue($button, 'keyParam', 'id');
      $attrs = ArrayHelper::getValue($button, 'attrs', []);
      Html::addCssClass($button, 'btn');
      Html::addCssClass($button, 'btn-sm');
      $buttonText = isset($button['text']) ? ' ' . $button['text'] : ''; 
      $data .= Html::a(
       $button['label'] . $buttonText,
       $url = $this->createUrl(
       $button['url'],
       $model,
       $key,
       $index,
       $appendReturnUrl,
       $url_append,
       $keyParam,
       $attrs
       ),
       ArrayHelper::merge(
       isset($button['options']) ? $button['options'] : [],
       [
        //'data-pjax' => 0,
        // 'data-action' => $button['url'],
        'class' => $button['class'],
        'title' => $button['label'],
       ]
       )
      ) . ' ';
     }
     $data .= '</div>'; 
     return $data;
     }

    }

2、Helper.php文件


    <?php

    use Yii;

    class Helper
    { 
     private static $returnUrl;
     public static $returnUrlWithoutHistory = false;

     /**
     * @param int $depth
     * @return string
     */
     public static function getReturnUrl()
     {
     if (is_null(self::$returnUrl)) {
      $url = parse_url(Yii::$app->request->url);
      $returnUrlParams = [];
      if (isset($url['query'])) {
      $parts = explode('&', $url['query']);
      foreach ($parts as $part) {
       $pieces = explode('=', $part);
       if (static::$returnUrlWithoutHistory && count($pieces) == 2 && $pieces[0] === 'returnUrl') {
       continue;
       }
       if (count($pieces) == 2 && strlen($pieces[1]) > 0) {
       $returnUrlParams[] = $part;
       }
      }
      }
      if (count($returnUrlParams) > 0) {
      self::$returnUrl = $url['path'] . '?' . implode('&', $returnUrlParams);
      } else {
      self::$returnUrl = $url['path'];
      }
     }
     return self::$returnUrl;
     }
    }

视图调用

1、直接调用,把Yii2自带的['class' => 'yiigridActionColumn']换成我们新写的['class' => 'common\components\ActionColumn']

2、如直接调用不能满足你的要求可以自定义链接,自定义链接的写法如下:


    [
     'class' => 'common\components\ActionColumn',
     'urlCreator' => function($action, $model, $key, $index) use ($id) {
     //自定义链接传的参数
     $params = [
      $action,
      'option_id' => $model->option_id, 
      'id' => $id,
     ];
     $params['returnUrl'] = common\components\Helper::getReturnUrl();
     return yii\helpers\Url::toRoute($params);
     },
     'buttons' => [
       [
       'url' =>'view',
       'class' => 'btn btn-success btn-xs',
       'label' => Yii::t('yii', 'View'),
       'appendReturnUrl' => false,//是否保留当前URL,默认为true
       'url_append' => '',
       'keyParam' => 'id', //是否传id,不传设置null
       ],
       [
       'url' => 'update',
       'class' => 'btn btn-primary btn-xs btn-sm',
       'label' => Yii::t('yii', 'Update'),
       'appendReturnUrl' => true,//是否保留当前URL,默认为true
       'url_append' => '',
       'keyParam' => 'id', //是否传id,不传设置null
       ],
       [
       'url' => 'delete',
       'class' => 'btn btn-danger btn-xs btn-sm',
       'label' => Yii::t('yii', 'Delete'),
       'options' => [
       'data-action' => 'delete',
       ],
       'appendReturnUrl' => true,//是否保留当前URL,默认为true
       'url_append' => '',
       'keyParam' => 'id', //是否传id,不传设置null
       ],
     ],

    ],

3、新增的话,这么引用<?= Html::a(Yii::t('yii', 'Create'), ['create','returnUrl' => Helper::getReturnUrl()], ['class' => 'btn btn-success']) ?>

控制器逻辑

1、用get获取returnUrl,代码:$returnUrl = Yii::$app->request->get('returnUrl');

2、跳转到的URL:return $this->redirect($returnUrl);

分析总结

1、此方法的好处是不动核心代码,调用方式保留了Yii2自带的方式。

2、不足之处是在自定义链接的时候需要把每一个操作update、view、delete都写出来,不能用这种'template' => '{view}{update}{delete}'简单且看着舒服能根据需求去写了。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
获取IMSI
将二进制数据转为16进制以便显示
获取IMEI
文件下载
贪吃蛇
双位运算符
PHP自定义函数获取搜索引擎来源关键字的方法
Java生成UUID
发送邮件
年的日历图
提取后缀名
在Zeus Web Server中安装PHP语言支持
让你成为最历害的git提交人
Yii2汉字转拼音类的实例代码
再谈PHP中单双引号的区别详解
指定应用ID以获取对应的应用名称
Python 2与Python 3版本和编码的对比
php封装的page分页类完整实例