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


Posted in PHP onJanuary 13, 2017

前言

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

需求分析

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

1、链接的效果图

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

封装代码

共有两个文件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 相关文章推荐
PHP面向对象的使用教程 简单数据库连接
Nov 25 PHP
php构造函数实例讲解
Nov 13 PHP
php中AES加密解密的例子小结
Feb 18 PHP
WordPress中缩略图的使用以及相关技巧
Nov 24 PHP
php 防止表单重复提交两种实现方法
Nov 03 PHP
php reset() 函数指针指向数组中的第一个元素并输出实例代码
Nov 21 PHP
php指定长度分割字符串str_split函数用法示例
Jan 30 PHP
PHP获取表单数据与HTML嵌入PHP脚本的实现
Feb 09 PHP
PHP命名空间namespace及use的简单用法分析
Aug 03 PHP
PHP实现单条sql执行多个数据的insert语句方法
Oct 11 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 PHP
tp5框架基于ajax实现异步删除图片的方法示例
Feb 10 PHP
PHP文件上传、客户端和服务器端加限制、抓取错误信息、完整步骤解析
Jan 12 #PHP
php中分页及SqlHelper类用法实例
Jan 12 #PHP
PHP生成图片验证码功能示例
Jan 12 #PHP
PHP中字符串长度的截取用法示例
Jan 12 #PHP
PHP实现二维数组去重功能示例
Jan 12 #PHP
PHP生成图片缩略图类示例
Jan 12 #PHP
php+redis实现多台服务器内网存储session并读取示例
Jan 12 #PHP
You might like
laravel通用化的CURD的实现
2019/12/13 PHP
javascript showModalDialog,open取得父窗口的方法
2010/03/10 Javascript
jQuery教程 $()包装函数来实现数组元素分页效果
2013/08/13 Javascript
js禁止回车提交表单的示例代码
2013/12/23 Javascript
js实现时间显示几天前、几小时前或者几分钟前的方法集锦
2015/05/29 Javascript
js实现图片无缝滚动
2015/12/23 Javascript
改变checkbox默认选中状态及取值的实现代码
2016/05/26 Javascript
jQuery多个版本和其他js库冲突的解决方法
2016/08/11 Javascript
js改变透明度实现轮播图的算法
2020/08/24 Javascript
AngularJS实现自定义指令与控制器数据交互的方法示例
2017/06/19 Javascript
关于Webpack dev server热加载失败的解决方法
2018/02/22 Javascript
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
在vue项目中集成graphql(vue-ApolloClient)
2018/09/08 Javascript
ng-zorro-antd 入门初体验
2018/12/03 Javascript
微信小程序转发事件实现解析
2019/10/22 Javascript
小程序登录之支付宝授权的实现示例
2019/12/13 Javascript
[04:10]2016国际邀请赛中国区预选赛第二日TOP10精彩集锦
2016/06/28 DOTA
[01:16:50]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第一场 3月7日
2021/03/11 DOTA
Python中的map、reduce和filter浅析
2014/04/26 Python
Python内置函数dir详解
2015/04/14 Python
Python中encode()方法的使用简介
2015/05/18 Python
Python小工具之消耗系统指定大小内存的方法
2018/12/03 Python
python使用zip将list转为json的方法
2018/12/31 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
2020/04/03 Python
canvas如何实现多张图片编辑的图片编辑器
2020/03/10 HTML / CSS
英语老师推荐信
2014/02/26 职场文书
乡镇信息公开实施方案
2014/03/23 职场文书
英语教育专业自荐信
2014/05/29 职场文书
森林防火标语
2014/06/23 职场文书
尊老爱亲美德少年事迹材料
2014/08/14 职场文书
教师批评与自我批评(群众路线)
2014/10/15 职场文书
幼儿园中班教师个人工作总结
2015/02/06 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书
WCG2010 星际争霸决赛 Flash vs Goojila 1 星际经典比赛回顾
2022/04/01 星际争霸
MySQL下载安装配置详细教程 附下载资源
2022/09/23 MySQL