[Yii2笔记]063数据小部件(Data widgets) [ 技术分享 ]
说明
学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!
原文网址:
http://www.yiiframework.com/doc-2.0/guide-output-data-widgets.html
本文主题:数据小部件(Data widgets)
Yii提供了一组小部件,它们可以用于显示数据。DetailView小部件可以用于显示一条记录的数据,ListView和GridView可以用于将数据显示为一个列表或表格,且可以实现分页、排序和筛选的功能。
1、DetailView(详情视图)
DetailView小部件显示一条记录的详细信息。它常用于以特定格式显示一个模型(例如:模型的每个属性显示为表格的一行)。模型可以是yii\base\Model或其子类(如Active Record)的实例,也可以是一个关联数组。
DetailView使用$attributes 属性来决定哪一个模型列将被显示出来,也会定义它们的显示格式,有效的格式化参数请参考formatter章节: http://www.yiiframework.com/doc-2.0/guide-output-formatting.html
DetailView典型用法如下例所示:
echo DetailView::widget([
'model' => $model,
//attributes
'attributes' => [
'title', // title列(纯文本)
'description:html', //description列格式化为HTML
[
'attribute' => 'tags',
'value' => function ($model) {
return implode(',',array_column($model->tags,'tag'));
},
],
[ //模型的ower name列
'label' => 'Owner',
'value' => $model->owner->name,
'captionOptions' => ['tooltip' => 'Tooltip'], //label的HTML标签添加自定义属性<th tooltip="Tooltip">Owner</th>
'contentOptions' => ['class' => 'text-right'], //value的HTML标签添加自定义属性<td class="text-right">Asia</td>
'visible' => false,//不显示此属性
// 'visible' => true,//显示此属性,默认值
],
[
//关联属性
'attribute'=> 'user.nickname',
'label'=>'Creater',
'value'=>function($model){
//获取关联属性的值
return $model['user']['nickname']." ".date("Y年n月j日 H:i:s",$model->createdAt);
},
'visible' => \Yii::$app->user->can('updatePost', ['post' => $model]),
],
//显示标签
[
'label' => 'All Tags',
'value' => function ($model) {
return implode(',',array_column($model->tags,'tag'));
},
],
[
'attribute' => 'owner',
'value' => function ($model) {
return $model->owner->name;
},
'visible' => \Yii::$app->user->can('posts.owner.view'),
],
[ //模型的ower name列
'label' => 'Owner',
'value' => $model->owner->name,
'captionOptions' => ['tooltip' => 'Tooltip'], //label的HTML标签添加自定义属性<th tooltip="Tooltip">Owner</th>
'contentOptions' => ['class' => 'text-right'], //value的HTML标签添加自定义属性<td class="text-right">Asia</td>
'visible' => false,//不显示此属性
// 'visible' => true,//显示此属性,默认值
],
'created_at:datetime', // creation date formatted as datetime
],
]);
记住:与yii\grid\GridView(原文档中是yii\widgets\GridView,错误!)处理一组模型不同,DetailView只处理一个模型。因为$model 是唯一的一个要在视图中有效并显示的模型,所以大多数时候无需使用闭包函数。 但有时也会使用到闭包函数,例如:当定义visible时,如果当此列的值为false时,你不想让它参与计算,就需要使用闭包函数了。
echo DetailView::widget([
'model' => $model,
'attributes' => [
[
'attribute' => 'owner',
'value' => function ($model) {
return $model->owner->name;
},
'visible' => \Yii::$app->user->can('posts.owner.view'),
],
],
]);
2、ListView(列表视图)
ListView小部件用于显示data provider提供的数据。每个数据模型使用一个特定的视图文件进行渲染。因为它提供了如分页、排序和筛选等特性,它被用于向终端用户显示信息或用于创建数据管理的UI。
一个典型用法如下例所示:
use yii\widgets\ListView;
use yii\data\ActiveDataProvider;
$dataProvider = new ActiveDataProvider([
'query' => Post::find(),
'pagination' => [
'pageSize' => 20,
],
]);
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_post',
'layout' => '{pager}{summary}{items}{summary}{pager}',//列表前后位置都显示翻页按钮和汇总信息
]);
_post视图文件包括以下内容:
<?php
use yii\helpers\Html;
use yii\helpers\HtmlPurifier;
?>
<div class="post">
<h2><?= Html::encode($model->title) ?></h2>
<?= HtmlPurifier::process($model->text) ?>
</div>
在这个视图文件中,当前的数据模型被定义为$model ,另外还有一些变量也可以被使用:
$key ,混合类型,与数据项相关联的键名
$index ,整型,数据提供者返回的数据项索引号,从0开始
$widget ,ListView类型,widget实例
如果你需要为视图传递更多的数据,你可以使用$viewParams 属性来定义键值对,代码如下:
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_post',
'viewParams' => [
'fullView' => true,
'context' => 'main-page',
// ...
],
]);
$viewParams 中的键值对在视图中可以直接作为变量来引用。
ListView实例:
D:\phpwork\basic\controllers\CountryController.php
public function actionList() {
return $this->render("list");
}
D:\phpwork\basic\views\country\list.php
<?php
use yii\widgets\ListView;
use yii\data\ActiveDataProvider;
$dataProvider=new ActiveDataProvider([
'query'=>\app\models\Country::find(),
'pagination'=>[
'pageSize'=>2,
],
]);
echo ListView::widget([
'dataProvider'=>$dataProvider,
'itemView'=>'_list',
'viewParams' => [
'fullView' => true,
'context' => 'main-page',
],
]);
D:\phpwork\basic\views\country_list.php
<?php
use yii\helpers\Html;
use yii\helpers\HtmlPurifier;
?>
<div class="post">
<h2><?= Html::encode($model->name) ?></h2>
<?= HtmlPurifier::process($model->population) ?>
key:<?=$key?>
index:<?=$index?>
context:<?=$context?>
<?
//var_dump($widget);
?>
</div>
测试结果:
http://localhost:8081/country/list?page=1&per-page=2
/*
Showing 1-2 of 8 items.
232233aabb
2245 key:58a14411e4017a1c16000029 index:0 context:main-page
china2
90 key:58aaad6a45940fd795f941b0 index:1 context:main-page
« 1 2 3 4 »
*/
3、GridView(网格视图)
数据格或GridView在Yii小部件中功能很强大,如果你要构建系统管理后台,使用它的地方会非常多。它从一个数据提供器(data provider)获取数据,并对每行数据进行渲染,渲染时是使用列设置将每个数据填充到表格单元。
表格中的每一行代表一条数据记录,列则代表记录的字段值(一些列可能会对应多字段的复杂表达式或静态文本)。 GridView的最小代码块如下所示:
use yii\grid\GridView;
use yii\data\ActiveDataProvider;
$dataProvider = new ActiveDataProvider([
'query' => Post::find(),
'pagination' => [
'pageSize' => 20,
],
]);
echo GridView::widget([
'dataProvider' => $dataProvider,
]);
以上代码先创建了一个数据提供器,然后使用Gridview显示每行的每个数据。显示的表格使用了排序和翻页功能。
实例,GridView基本实例
D:\phpwork\basic\controllers\BlogController.php
class BlogController extends Controller{
public function actionIndex(){
$dataProvider = new ActiveDataProvider([
'query' => Blog::find(),
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
}
D:\phpwork\basic\views\blog\index.php
<?php Pjax::begin(); ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'title',
'content:ntext',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<?php Pjax::end(); ?></div>
网格列(Grid columns)
在GridView中可以配置columns属性,这些Grid表格列是以yii\grid\Column类的方式来配置的。根据这些列的类型和设置可以代表不同的数据。默认类是yii\grid\DataColumn,代表一个模型属性,可以排序和过滤。
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//普通列使用$dataProvider中包含的列名来定义,数据将从模型的属性中获取。
'id',
'username',
//更复杂的一个列定义
[
'class' => 'yii\grid\DataColumn', //默认值,可以省略
'value' => function ($data) {
return $data->name; //数组数据$data['name'],例如使用SqlDataProvider
},
],
],
]);
注意如果配置中的columns未定义,Yii将尽可能的展现数据提供器模型中的数据列。
列类(Column classes)
网格列可以使用不同的列类来自定义:
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
[
'class' => 'yii\grid\SerialColumn',
//在此你可以定义附加的属性
],
Yii提供了4种列类:数据列(Data column)、动作列(Action column)、复选框列(Checkbox column)、序号列(Serial column) 除了使用Yii提供的列类之外,你还要吧创建自己的列类,稍后你将看到这种况。 每个列类都扩展自yii\grid\Column,所以在配置网格列时,可以配置公共的选项: header,设置头行的内容 footer,设置尾行的内容 visible,定义该列是否可见 content,你可以传递一个PHP回调函数,它的返回值将作为行数据,格式为:
function ($model, $key, $index, $column) {
return 'a string';
}
你可以使用数组定义不同的HTML容器选项: headerOptions footerOptions filterOptions contentOptions
数据列(Data column)
yii\grid\DataColumn 数据列用于显示和排序数据,它是默认的列类型,当使用这种类型时可以省略它。 数据列的主要设置是它的format属性,它的值对应于formatter应用组件中默认Formatter的方法:
echo GridView::widget([
'columns' => [
[
'attribute' => 'name',
'format' => 'text'
],
[
'attribute' => 'birthday',
'format' => ['date', 'php:Y-m-d']
],
],
]);
如上代码所示,text对应于yii\i18n\Formatter::asText()方法。列值将被作为第1个参数传送过去。在第二个列定义中,date对应于yii\i18n\Formatter::asDate()方法。列值将被作为第1个参数,'php:Y-m-d'被作为第2个参数传送过去。 关于有效的格式化器请参见Data Formattin章节: http://www.yiiframework.com/doc-2.0/guide-output-formatting.html
在columns的API文档中有关于配置列的快捷格式: http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html#$columns-detail
动作列(Action column)
动作列显示动作按钮,如每行记录的更新或删除操作等。
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
[
'class' => 'yii\grid\ActionColumn',
//可以在这里配置附加的属性
],
你可以配置的附加属性是: 1、controller,操作这些动作的控制器ID,如果没有设置,将使用当前控制器。 2、template,定义动作列中每个单元格所使用的模板。在模型中,大括号包含的标签将作为控制器的动作ID(在动作列中也被称为按钮名称),它们将被定义在buttons中的闭包函数所替换,例如,标签{view}将被替换为buttons['view'],如果闭包函数没有找到,则标签将被替换成空字符串。默认的标签是{view} {update} {delete} 3、buttons,是一个数组,包含了按钮渲染的闭包函数。数组键名是按钮名称(没有大括号),键值是对应的按钮渲染闭包函数,此函数可以使用以下格式:
function ($url, $model, $key) {
//返回按钮的HTML代码
}
在上述代码中,$url 是按钮指向的URL,$model 是当前行渲染的模型对象,$key 是数据提供器数组模型的键名。 4、urlCreater,是一个闭包函数,它使用模型的特定信息创建一个按钮URL,闭包函数的格式与yii\grid\ActionColumn::createUrl()相同,如果此属性没有设置,按钮的URL将使用yii\grid\ActionColumn::createUrl()创建。 5、visibleButtons,是一个数组,定义了每个按钮可以查看到的条件。数组键名是按钮名(没有大括号),键值是布尔型true/false或者是一个匿名函数。当按钮名在数据中没有定义,它将默认被显示出来,闭包函数须使用如下格式:
function ($model, $key, $index) {
return $model->status === 'editable';
}
或者你也可以传递一个布尔值:
[
'update' => \Yii::$app->user->can('update')
]
Action column实例://ActionColumn
D:\phpwork\news\views\articles\index.php
//使用图标按钮,增加按钮间距,增加了权限判断
[
'header' => '操作',
'class' => 'yii\grid\ActionColumn',
'options'=>['style'=>'width: 100px;'],
'buttons'=>[
'view'=> function ($url, $model, $key) {
$options = [
'title' => Yii::t('app', 'View'),
'aria-label' => Yii::t('app', 'View'),
'data-pjax' => '0',
'style'=>'padding:0 5px',
];
return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', $url, $options);
},
'update'=> function ($url, $model, $key) {
//使用权限判断
if(\Yii::$app->user->can('updatePost', ['post' => $model])){
$options = [
'title' => Yii::t('app', 'Update'),
'aria-label' => Yii::t('app', 'Update'),
'data-pjax' => '0',
'style'=>'padding:0 5px',
];
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, $options);
}
},
'delete'=> function ($url, $model, $key) {
if(\Yii::$app->user->can('updatePost', ['post' => $model])){
$options = [
'title' => Yii::t('app', 'Delete'),
'aria-label' => Yii::t('app', 'Delete'),
'data-pjax' => '0',
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'style'=>'padding:0 5px',
];
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, $options);
}
},
],
],
D:\phpwork\basic\views\country\grid.php
//使用文字链接
[
'header' => 'Operations',
'class' => 'yii\grid\ActionColumn',
'options'=>['style'=>'width: 250px;'],
'buttons'=>[
'view'=> function ($url, $model, $key) {
$options = [
'title' => Yii::t('app', 'View'),
'aria-label' => Yii::t('app', 'View'),
'data-pjax' => '0',
'class'=>'btn btn-circle btn-icon-only blue',
];
return Html::a('View', $url, $options);
},
'update'=> function ($url, $model, $key) {
$options = [
'title' => Yii::t('app', 'Update'),
'aria-label' => Yii::t('app', 'Update'),
'data-pjax' => '0',
'class'=>'btn btn-circle btn-icon-only green',
];
return Html::a('Update', $url, $options);
},
'delete'=> function ($url, $model, $key) {
$options = [
'title' => Yii::t('app', 'Delete'),
'aria-label' => Yii::t('app', 'Delete'),
'data-pjax' => '0',
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'class'=>'btn btn-circle btn-icon-only red',
];
return Html::a('Delete', $url, $options);
},
],
],
<span class="glyphicon glyphicon-eye-open"></span>
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-trash"></span>
复选框列(Checkbox column)
复选框列显示了一列复选框。 要为GridView添加一个CheckboxColumn,需要在columns中进行如下配置:
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
// ...
[
'class' => 'yii\grid\CheckboxColumn',
//添加其他配置项
],
],
用户可以在复选框上点击以选中网格的一行,要获取选中的行可以在JavaScript代码中调用以下代码:
var keys=$('#grid').yiiGridView('getSelectedRows');
//keys是与选定行相关联键名的数组。
//序号列(Serial column)
序号列显示了每一行的行号,从1开始计数。
使用示例如下:
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'], // <-- here
// ...
数据排序(Sorting data)
数据过滤(Filtering data)
要实现数据过滤,网格需要一个具有搜索标准的模型,它会从GridView表格中获取过滤项。使用Active Record的一个最佳实践是创建一个搜索模型类,使用它提供必需的功能(可以使用Gii生成它),这个类定义了GridView表格过滤项的验证规则,提供了一个search()方法,它将使用搜索关键字生成特定查询,并返回一个数据提供器。 要为Post模型添加搜索功能,我们可以使用以下代码创建一个PostSearch模型:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
class PostSearch extends Post
{
public function rules()
{
// only fields in rules() are searchable
return [
[['id'], 'integer'],
[['title', 'creation_date'], 'safe'],
];
}
public function scenarios()
{
//使用Model的默认场景,从而跳过父类Post的场景
return Model::scenarios();
}
public function search($params)
{
$query = Post::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// load the search form data and validate
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
// adjust the query by adding the filters
$query->andFilterWhere(['id' => $this->id]);
$query->andFilterWhere(['like', 'title', $this->title])
->andFilterWhere(['like', 'creation_date', $this->creation_date]);
return $dataProvider;
}
}
小贴士:如何构建查询语句请查看Query Builder中的Filter Conditions部分: http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html#filter-conditions
你可以在控制器中使用此方法为GridView获取数据提供器(Data Provider):
$searchModel=new PostSearch();
$dataProvider=$searchModel->search(Yii::$app->request->get());
return $this->render('myview',[
'dataProvider'=>$dataProvider,
'searchModel'=>$searchModel,
]);
在视图中你可以填充$dataProvider 和$searchModel 到GridView中去:
echo GridView::widget([
'dataProvider'=>$dataProvider,
'filterModel'=>$searchModel,
'columns'=>[
//...
],
]);
实例,数据过滤实例,单独过滤器表单实例
D:\phpwork\basic\controllers\BlogController.php
namespace app\controllers;
use Yii;
use app\models\Blog;
use app\models\BlogSearch;
class BlogController extends Controller
{
public function actionIndex()
{
$filterModel=new BlogSearch();
$dataProvider=$filterModel->search(Yii::$app->request->get());
return $this->render('index',[
'dataProvider'=>$dataProvider,
'filterModel'=>$filterModel,
]);
}
}
D:\phpwork\basic\models\Blog.php
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "blog".
*
* @property string $id
* @property string $title
* @property string $content
*/
class Blog extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'blog';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['content'], 'string'],
[['title'], 'string', 'max' => 50],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'title' => Yii::t('app', 'Title'),
'content' => Yii::t('app', 'Content'),
];
}
/**
* @inheritdoc
* @return BlogQuery the active query used by this AR class.
*/
public static function find()
{
return new BlogQuery(get_called_class());
}
//beforeSave
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if($insert){
$this->create_at=time();
}
$this->update_at=time();
return true;
} else {
return false;
}
}
}
D:\phpwork\basic\models\BlogSearch.php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
class BlogSearch extends Blog
{
public $createdFrom;
public $createdTo;
public function rules()
{
// only fields in rules() are searchable
return [
[['_id','title', 'content','createdFrom','createdTo'], 'safe'],
];
}
public function scenarios()
{
//使用Model的默认场景,从而跳过父类Blog的场景
return Model::scenarios();
}
public function search($params){
$query = Blog::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 20,
],
]);
// load the search form data and validate
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$createdFrom=($this->createdFrom!="")?strtotime($this->createdFrom):"";
$createdTo=($this->createdTo!="")?strtotime($this->createdTo):"";
// adjust the query by adding the filters
$query->andFilterWhere(['like', 'title', $this->title])
->andFilterWhere(['like', 'content', $this->content]);
$query->andFilterWhere(['>=', 'create_at', $createdFrom])
->andFilterWhere(['<=', 'create_at', $createdTo]);
return $dataProvider;
}
}
D:\phpwork\basic\views\blog\index.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\Pjax;
/* @var $this yii\web\View */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Blogs';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="blog-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a('Create Blog', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?php Pjax::begin(); ?>
<?= $this->render('_search', ['model' => $filterModel]) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $filterModel,
//columns
'columns' => [
[
'class' => 'yii\grid\SerialColumn',
],
'id',
'title',
'content',
'content:ntext',
//简写格式:attribute:format:label
'amount:currency:Total Amount',
//对content进行格式转换
[
'attribute' => 'content',
'value' => function ($model) {
if($model->format==1){
return $model->content;
}else{
return Markdown::convert($model->content);
}
},
'format'=>'text',
],
//create_at
[
'attribute' => 'create_at',
'value' => function ($model,$key,$index, $column) {
//$model,当前的模型;$key,当前记录的键名;$index,当前记录的索引;$column,当前列的配置(是一个DataColumn对象)
return date("Y-n-j",$model->create_at).',key:'.$key.',index:'.$index.',columnAttribute:'.$column->attribute;
//第3条记录的返回值:2017-3-24,key:3,index:2,columnAttribute:create_at
},
],
[
'class' => 'yii\grid\ActionColumn',
],
],
]); ?>
<?php Pjax::end(); ?></div>
<? D:\phpwork\basic\views\blog_search.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model app\models\PostSearch */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="post-search">
<?php $form = ActiveForm::begin([
'action' => ['index'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'content') ?>
<?= $form->field($model, 'createdFrom')->textInput(['type'=>"date"]) ?>
<!--<input type="date" id="blogsearch-createdfrom" class="form-control" name="BlogSearch[createdFrom]"> -->
<?= $form->field($model, 'createdTo')->textInput(['type'=>"date"]) ?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
<?= Html::submitButton('Reset', ['class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
单独的过滤器表单
大多数情况下使用GridView头部过滤器就足够了,但有时你可能还需要一个单独的过滤器表单,你可以很容易就把它添加上。你可以创建一个局部视图(partial view)文件_search.php,代码如下:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model app\models\PostSearch */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="post-search">
<?php $form = ActiveForm::begin([
'action' => ['index'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'creation_date') ?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
<?= Html::submitButton('Reset', ['class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<? 在index视图中添加_search.php
<?= $this->render('_search', ['model' => $searchModel]) ?>
注意:如果你是使用Gii生成的CRUD代码,默认情况下单独过滤器表单(_search.php)已经生成好了,仅仅是在index.php视图中被注释掉了而已,将注释去掉就可以使用了。
当你使用不在GridView中显示的字段或对特殊条件过滤时,单独过滤器表单就非常有用了。要过滤日期范围,我们可以添加非数据库属性createFrom和createTo到搜索模型:
class PostSearch extends Post
{
/**
* @var string
*/
public $createdFrom;
/**
* @var string
*/
public $createdTo;
}
在search()方法中扩展查询条件如下所示:
$query->andFilterWhere(['>=', 'creation_date', $this->createdFrom])
->andFilterWhere(['<=', 'creation_date', $this->createdTo]);
然后添加相应字段到过滤表单中:
<?= $form->field($model, 'creationFrom') ?>
<?= $form->field($model, 'creationTo') ?>
操作关联模型(Working with model relations)
在GridView中显示活动记录(active records)时,你或许会感到这种情况,在显示作者列时,你想要显示的是作者的姓名,而不是他的id。要实现这个目标,你只需在yii\grid\GridView::$columns 中定义属性名称为author.name即可,当然,首先需要在Post模型中存在与author模型的关联,并且在author模型中有一个name属性。GridView将显示作者名称,但是默认情况下对这个字段是无法进行排序和过滤筛选的。你可以调整上节中介绍的PostSearch模型添加这两项功能。 要对关联列排序,你需要添加关联表并添加排序规则到数据提供器的排序组件中去:
$query = Post::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
//与author关联的表是user,并设置author表的别名是 author
// and set the table alias to be `author`
$query->joinWith(['author' => function($query) { $query->from(['author' => 'users']); }]);
//从 2.0.7版本开始,上一行代码可以简写为$query->joinWith('author AS author')
//使关联列排序生效
$dataProvider->sort->attributes['author.name'] = [
'asc' => ['author.name' => SORT_ASC],
'desc' => ['author.name' => SORT_DESC],
];
// ...
过滤操作也如上例一样需要使用joinWith调用,你也需要定义列的搜索功能和规则,代码如下:
public function attributes()
{
// add related fields to searchable attributes
return array_merge(parent::attributes(), ['author.name']);
}
public function rules()
{
return [
[['id'], 'integer'],
[['title', 'creation_date', 'author.name'], 'safe'],
];
}
然后在search()中你添加一个过滤条件:
$query->andFilterWhere(['LIKE', 'author.name', $this->getAttribute('author.name')]);
信息:在上例中,我们为表别名和关联名称都使用的是相同的名称,当你的别名和关联名不相同时,你要注意别名和关联名的所用之处。一个简单规律是在每个需要构建数据库查询的地方使用别名,在其他地方,如attributes()和rules()等地方都使用关联名称。
例如,你为关联表author使用别名au,joinWith语句就是这样:
$query->joinWith(['author au']);
当别名定义在关联定义中,则会使用到如下调用:
$query->joinWith(['author']);
别名用于过滤条件,但是属性名称中要保持原样:
$query->andFilterWhere(['like','au.name',$this->getAttribute('author.name')]);
排序的定义也是同样的道理:
$dataProvider->sort->attributes['author.name'] = [
'asc' => ['au.name' => SORT_ASC],
'desc' => ['au.name' => SORT_DESC],
];
在定义默认排序时,你需要使用关联名称而不能使用别名:
$dataProvider->sort->defaultOrder = ['author.name' => SORT_ASC];
信息:关于joinWith和后台查询性能的更多信息,请查看“active record docs on joining with relations”文档: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#joining-with-relations
实例,在GridView的查询中使用关联属性别名//relationGridView
// GridView默认是按作者反向排序,可以在页面表格中对作者排序进行更改 D:\phpwork\basic\controllers\BlogController.php
class BlogController extends Controller
{
public function actionIndex()
{
$filterModel=new BlogSearch();
$dataProvider=$filterModel->search(Yii::$app->request->get());
//设置默认排序时要使用全称:author.name
$dataProvider->sort->defaultOrder = ['author.name' => SORT_DESC];
return $this->render('index',[
'dataProvider'=>$dataProvider,
'filterModel'=>$filterModel,
]);
}
D:\phpwork\basic\models\BlogSearch.php
class BlogSearch extends Blog
{
public function search($params){
$query = Blog::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 20,
],
]);
$query->joinWith(['author au']);
//$query->joinWith(['author as au']);//与上句等效
//别名au只能在sql语句中使用,在获取属性时还要使用全称author.name
$dataProvider->sort->attributes['author.name'] = [
'asc' => ['au.name' => SORT_ASC],
'desc' => ['au.name' => SORT_DESC],
];
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$createdFrom=($this->createdFrom!="")?strtotime($this->createdFrom):"";
$createdTo=($this->createdTo!="")?strtotime($this->createdTo):"";
$query->andFilterWhere(['like', 'title', $this->title])
->andFilterWhere(['like', 'content', $this->content]);
$query->andFilterWhere(['>=', 'create_at', $createdFrom])
->andFilterWhere(['<=', 'create_at', $createdTo]);
//别名au只能在sql语句中使用,在获取属性时还要使用全称author.name
$query->andFilterWhere(['LIKE', 'au.name', $this->getAttribute('author.name')]);
return $dataProvider;
}
D:\phpwork\basic\models\Blog.php
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "blog".
*
* @property string $id
* @property string $title
* @property string $content
*/
class Blog extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'blog';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['content'], 'string'],
[['title'], 'string', 'max' => 50],
[$this->attributes(),'safe'],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'title' => Yii::t('app', 'Title'),
'content' => Yii::t('app', 'Content'),
'author.name'=>'作者',
];
}
/**
* @inheritdoc
* @return BlogQuery the active query used by this AR class.
*/
public static function find()
{
return new BlogQuery(get_called_class());
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if($insert){
$this->create_at=time();
}
$this->update_at=time();
return true;
} else {
return false;
}
}
public function getAuthor() {
return $this->hasOne(Author::className(), ['id' => 'authorid']);
}
}
D:\phpwork\basic\config\web.php
<?php
$params = require(__DIR__ . '/params.php');
$db = require(__DIR__ . '/db-local.php');
$mongodb = require(__DIR__ . '/mongodb-local.php');
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
'db' => $db,
'mongodb' => $mongodb,
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'xinxZ50CwklfrgV3ORZfEgoWQIqUEtlm',
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
//prettyUrl,//urlManager
'urlManager' => [
'class' => 'yii\web\UrlManager',
'showScriptName' => false,
'enablePrettyUrl' => true,
'rules' => array(
//mongoDB的详情页地址:http://localhost:8082/country/view/58899feae4017a740c000029
'<controller:\w+>/view/<id:\w+>' => '<controller>/view',
//'<controller:\w+>/<id:\d+>' => '<controller>/view',//mysql详情页的写法
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
//D:\phpwork\b2b\imall\frontend\config\main.php
'rules' => array(
'site/<urlKey:.+>/productdetail' => 'site/productdetail',
'promotion/<name:\w+>' => 'promotion/index',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
],
/*
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
*/
],
'modules' => [
'admin' => [
'class' => 'app\modules\admin\Module',
],
],
// 'language' => 'en',
'language' => 'zh-CN',
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
];
}
return $config;
D:\phpwork\basic\config\db-local.php
<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yiibasic',
'username' => 'yiiuser',
'password' => 'jkljl23asdf23oickxvzklqwer',
'charset' => 'utf8',
];
D:\phpwork\basic\config\mongodb-local.php
<?php
return [
'class' => 'yii\mongodb\Connection',
'dsn' => 'mongodb://yiibaseuser:ycj123456@127.0.0.1:27017/yiibase',
];
使用SQL视图过滤、排序和显示数据(Using SQL views for filtering,sorting and displaying data)
有另外一种方法可以更快也更有效——SQL视图(views),例如,如果我们需要显示users和相关信息的GridView时,我们可以使用如下代码:
CREATE OR REPLACE VIEW vw_user_info AS
SELECT user.*, user_profile.lastname, user_profile.firstname
FROM user, user_profile
WHERE user.id = user_profile.user_id
然后你需要创建ActiveRecord来展现这个SQL视图:
namespace app\models\views\grid;
use yii\db\ActiveRecord;
class UserView extends ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'vw_user_info';
}
public static function primaryKey()
{
return ['id'];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
// define here your rules
];
}
/**
* @inheritdoc
*/
public static function attributeLabels()
{
return [
// define here your attribute labels
];
}
}
在search模型中你可以使用这个UserView AR模型,无需使用额外的排序和过滤属性定义,所有的属性都可以即选即用。注意使用此方法有以下优缺点: 1、你无需定义不同的排序和过滤条件,开箱即用; 2、因为数据量少,执行的SQL查询次数少,所以它的执行速度可以非常快(对于每个关联你无需进行额外的查询) 3、因为这仅是一个简单的SQL视图到UI的映射,缺少了在实际应用中的逻辑,所以如果你有一些方法,如isActive、isDeleted或其他将要影响UI的,你需要在类中复制它们。
实例,SQL视图实例
//创建SQL视图:
CREATE OR REPLACE VIEW view_author_info AS
SELECT author.*, author_info.lastname, author_info.firstname
FROM author, author_info
WHERE author.id = author_info.authorid
D:\phpwork\basic\controllers\AuthorsqlController.php
use app\models\AuthorViewSearch;
class AuthorsqlController extends Controller
{
public function actionIndexinfo()
{
$searchModel = new AuthorViewSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->sort->defaultOrder = ['name' => SORT_ASC];//定义默认排序方式
return $this->render('indexinfo', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
D:\phpwork\basic\models\AuthorViewSearch.php
<?php
namespace app\models;
use Yii;
use yii\data\ActiveDataProvider;
class AuthorViewSearch extends AuthorView {
public function rules() {
return [//标记为safe的属性将在表格中显示搜索框
[['name', 'firstname', 'lastname'], 'safe'],];
}
public function search($params) {
$query = AuthorView::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 20,//定义每页显示的记录数
],
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
//添加查询筛选条件
$query->andFilterWhere(['like', 'name', $this->name])->andFilterWhere(['like', 'firstname', $this->firstname])->andFilterWhere(['like', 'lastname', $this->lastname]);
return $dataProvider;
}
}
D:\phpwork\basic\views\authorsql\indexinfo.php
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a(Yii::t('app', 'Create Author'), ['create'], ['class' => 'btn btn-success']) ?>
<?= Html::a('Blog List', ['/blog/index'], ['class' => 'btn btn-default']) ?>
<?= Html::a('Author List', ['/authorsql/index'], ['class' => 'btn btn-default']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'name',
'firstname',
'lastname',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
测试结果:
http://localhost:8081/authorsql/indexinfo
/*
AuthorsInfo
1 Bomer Tang Bomer
2 gulong Gu Long
3 jingyong Jin Yong
4 Johns Xi Johns
*/
在页面中使用多个GridView(Multiple GridViews on one page)
你可以在一个页面中使用多个GridView,但是需要你做一些配置,以避免它们相互干扰。当使用GridView的多实例时,你需要配置不同的排序和分页链接参数,这样每个GridView才能按照它自己的排序和分页正常操作。需要设置的是dataProvider的sort和pagination实例的排序参数(sortParam)和分页参数(pageParam)。 假定我们想要列出Post和User模型,我们已经准备好了两个数据提供器:$userProvider 和$postProvider :
use yii\grid\GridView;
$userProvider->pagination->pageParam = 'user-page';
$userProvider->sort->sortParam = 'user-sort';
$postProvider->pagination->pageParam = 'post-page';
$postProvider->sort->sortParam = 'post-sort';
echo '<h1>Users</h1>';
echo GridView::widget([
'dataProvider' => $userProvider,
]);
echo '<h1>Posts</h1>';
echo GridView::widget([
'dataProvider' => $postProvider,
]);
实例,在一个页面显示多个GridView实例,显示两个GridView//twoGridView
D:\phpwork\basic\controllers\AuthorsqlController.php
use Yii;
use app\models\AuthorSearch;
use app\models\BlogSearch;
class AuthorsqlController extends Controller
{
public function actionMultiple()
{
//创建Author搜索模型实例
$searchModel = new AuthorSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);//获取查询参数
//配置Author的分页参数名称
$dataProvider->pagination->pageParam = 'author-page';
//配置Author的排序参数名称
$dataProvider->sort->sortParam = 'author-sort';
$dataProvider->pagination->pageSize = 1;//每页显示的记录数量
//创建Blog搜索模型实例
$blogModel=new BlogSearch();
$blogProvider=$blogModel->search(Yii::$app->request->get());//获取查询参数的另外一种写法
//配置Blog的分页参数名称
$blogProvider->pagination->pageParam = 'blog-page';
//配置Blog的排序参数名称
$blogProvider->sort->sortParam = 'blog-sort';
$blogProvider->pagination->pageSize = 2;
return $this->render('multiple', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'blogProvider'=>$blogProvider,
'blogModel'=>$blogModel,
]);
}
D:\phpwork\basic\models\AuthorSearch.php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Author;
/**
* AuthorSearch represents the model behind the search form about `app\models\Author`.
*/
class AuthorSearch extends Author
{
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id'], 'integer'],
[['name'], 'safe'],
];
}
/**
* @inheritdoc
*/
public function scenarios()
{
//使用Model的默认场景,从而跳过直接父类的场景
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params)
{
$query = Author::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
]);
$query->andFilterWhere(['like', 'name', $this->name]);
return $dataProvider;
}
}
D:\phpwork\basic\models\Author.php
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "author".
*
* @property integer $id
* @property string $name
*/
class Author extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'author';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['name'], 'string', 'max' => 20],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'name' => Yii::t('app', 'Name'),
];
}
public function getBlogs(){
return $this->hasMany(Blog::className(),['authorid'=>'id']);
}
public function getArticle() {
return $this->hasMany(Articlesql::className(),['authorId'=>'id']);
}
}
D:\phpwork\basic\models\BlogSearch.php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
class BlogSearch extends Blog
{
public $createdFrom;
public $createdTo;
public function attributes()
{
//添加关联属性到到可搜索列表中去,在GridView中才会出现作者的搜索框
return array_merge(parent::attributes(), ['author.name']);
}
public function rules()
{
return [
//只有在rules中的属性才能被搜索
[['_id','title', 'content','createdFrom','createdTo','author.name'], 'safe'],
// [$this->attributes(),'safe'],//使用此句更方便,可以实现更多字段的自动扩展
];
}
public function scenarios()
{
//使用Model的默认场景,从而跳过直接父类的场景
return Model::scenarios();
}
public function search($params){
$query = Blog::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 20,
],
]);
$query->joinWith(['author au']);//获取author关联属性,在GridView中才能引用author.name
//$query->joinWith(['author as au']);//与上句等效
//别名au只能在sql语句中使用,在获取属性时还要使用全称author.name
//增加sort属性才可以在GridView中显示排序链接
$dataProvider->sort->attributes['author.name'] = [
'asc' => ['au.name' => SORT_ASC],
'desc' => ['au.name' => SORT_DESC],
];
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$createdFrom=($this->createdFrom!="")?strtotime($this->createdFrom):"";
$createdTo=($this->createdTo!="")?strtotime($this->createdTo):"";
$query->andFilterWhere(['like', 'title', $this->title])
->andFilterWhere(['like', 'content', $this->content]);
$query->andFilterWhere(['>=', 'create_at', $createdFrom])
->andFilterWhere(['<=', 'create_at', $createdTo]);
//别名au只能在sql语句中使用,在获取属性时还要使用全称author.name
//在GridView的输入框中填写的关键字才会在author.name字段中进行搜索
$query->andFilterWhere(['LIKE', 'au.name', $this->getAttribute('author.name')]);
return $dataProvider;
}
}
D:\phpwork\basic\models\Blog.php
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "blog".
*
* @property string $id
* @property string $title
* @property string $content
*/
class Blog extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'blog';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['content'], 'string'],
[['title'], 'string', 'max' => 50],
[$this->attributes(),'safe'],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'title' => Yii::t('app', 'Title'),
'content' => Yii::t('app', 'Content'),
'author.name'=>'作者',
];
}
/**
* @inheritdoc
* @return BlogQuery the active query used by this AR class.
*/
public static function find()
{
return new BlogQuery(get_called_class());
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if($insert){
$this->create_at=time();
}
$this->update_at=time();
return true;
} else {
return false;
}
}
public function getAuthor() {
return $this->hasOne(Author::className(), ['id' => 'authorid']);
}
}
D:\phpwork\basic\views\authorsql\multiple.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* @var $this yii\web\View */
/* @var $searchModel app\models\AuthorSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Authors');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="author-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a(Yii::t('app', 'Create Author'), ['create'], ['class' => 'btn btn-success']) ?>
<?= Html::a('Blog List', ['/blog/index'], ['class' => 'btn btn-default']) ?>
<?= Html::a('AuthorInfo List', ['/authorsql/indexinfo'], ['class' => 'btn btn-default']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'name',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
<h1>Blog</h1>
<?= GridView::widget([
'dataProvider' => $blogProvider,
'filterModel' => $blogModel,//将此行注释掉即可将GridView中的搜索框隐藏掉
'columns' => [
[
'class' => 'yii\grid\SerialColumn',
],
'title',
'content',
[
'attribute' => 'create_at',
'value' => function ($model,$key,$index, $column) {
//$model,当前的模型;$key,当前记录的键名;$index,当前记录的索引;$column,当前列的配置(是一个DataColumn对象)
return date("Y-n-j",$model->create_at);
// return date("Y-n-j",$model->create_at).',key:'.$key.',index:'.$index.',columnAttribute:'.$column->attribute;
//第3条记录的返回值:2017-3-24,key:3,index:2,columnAttribute:create_at
},
],
'author.name',//显示作者名称,而不是id
[
'class' => 'yii\grid\ActionColumn',
],
],
]); ?>
</div>
测试结果:
http://localhost:8081/authorsql/multiple
http://localhost:8081/authorsql/multiple?author-page=4&per-page=1&blog-page=2&blog-sort=content&author-sort=name
/*
Authors
Create Author Blog List AuthorInfo List
第3-3条,共5条数据.
# Name
3 jingyong
« 1 2 3 4 5 »
Blog
第1-2条,共6条数据.
# Title Content Create At 作者
1 PHP is Ok! PHP is Ok! Content! 2017-3-24 Plark
2 My blog2 My blog Content2 2017-3-24 Johns
« 1 2 3 »
*/
在GridView中使用Pjax
Pjax小部件允许你更新一个页面中的特定部分,而不是重新加载整个页面,你可以使用它在过滤数据时仅更新GridView的内容部分。
use yii\widgets\Pjax;
use yii\grid\GridView;
Pjax::begin([
// PJax options
]);
Gridview::widget([
// GridView options
]);
Pjax::end();
在Pjax小部件中为链接定义Pjax::$linkSelector ,则Pjax也可以正常运行。但对于ActionColumn中的链接来说会存在问题,要避免此种情况发生,可以通过编辑ActionColumn::$buttons 属性,在链接中添加HTML选项data-pjax="0"。
//默认情况下,Yii2已将操作按钮的data-pjax设置为0
<a href="/authorsql/1" title="查看" aria-label="查看" data-pjax="0"><span class="glyphicon glyphicon-eye-open"></span></a>
<a href="/authorsql/update/1" title="更新" aria-label="更新" data-pjax="0"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="/authorsql/delete/1" title="删除" aria-label="删除" data-pjax="0" data-confirm="您确定要删除此项吗?" data-method="post"><span class="glyphicon glyphicon-trash"></span></a>
//第3页的链接代码:
<a href="/authorsql/pjax?page=3&per-page=1&sort=id&_pjax=%23p0" data-page="2">3</a>
实例,Pjax在GridView中的应用
D:\phpwork\basic\controllers\AuthorsqlController.php
public function actionPjax()
{
$searchModel = new AuthorSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->pagination->pageSize=1;
return $this->render('pjax', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
D:\phpwork\basic\views\authorsql\pjax.php
<?php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\Pjax;
/* @var $this yii\web\View */
/* @var $searchModel app\models\AuthorSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Authors-Pjax');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="author-index">
<h1><?= Html::encode($this->title) ?></h1>
<?= Html::a(Yii::t('app', 'Create Author'), ['create'], ['class' => 'btn btn-success']) ?>
<?= Html::a('Blog List', ['/blog/index'], ['class' => 'btn btn-default']) ?>
<?= Html::a('AuthorInfo List', ['/authorsql/indexinfo'], ['class' => 'btn btn-default']) ?>
</p>
<!-- 链接点击后,此时间值如果变化了,则说明Pjax没有生效;否则Pjax正在起作用-->
<?=time()?>
<?
Pjax::begin([
// 'linkSelector'=>false,//false,将Pjax中的链接取消Pjax点击效果,仅对链接有效,对于搜索筛选框无效。
'linkSelector'=>null,//null,默认值,Pjax中的所有链接自动触发Pjax点击效果,仅对局部页面做更新操作。
]);
//需要echo才能显示出来内容
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'name',
[
'class' => 'yii\grid\ActionColumn',
'contentOptions' => ['class' => 'text-center'],//将操作链接按钮居中
],
],
]);
Pjax::end();
?>
</div>
<? //在Gii中GridView/ListView中使用Pjax(GridView/ListView with Pjax in Gii) 自2.0.5版本起,Gii的CRUD生成器有一个选项叫作$enablePjax ,此选项可以在web页面或命令行中使用。
yii gii/crud --controllerClass="backend\\controllers\PostController" \
--modelClass="common\\models\\Post" \
--enablePjax=1
将生成一个Pjax小部件,它将GridView或ListView小部件包裹在其中。
4、Further reading(深入阅读)
Arno Slatius所著的Rendering Data in Yii 2 with GridView: https://www.sitepoint.com/rendering-data-in-yii-2-with-gridview-and-listview/
(全文完)
共 0 条回复
阿江
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276