先给出一个search类的代码:
namespace common\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use common\models\VPost;
use yii\db\Query;
use yii\helpers\HtmlPurifier;
/**
1. VPostSearch represents the model behind the search form about `common\models\VPost`.
*/
class VPostSearch extends VPost
{
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id', 'answer_num', 'user_id', 'created_at', ], 'integer'],
//注意,rules方法可以是post类部分字段,也可以是全部字段
];
}
/**
* @inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params)
{
$query = VPost::find();
$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;
}
//过滤发生在此处
$query->andFilterWhere([
'id' => $this->id,
'answer_num' => $this->answer_num,
'user_id' => $this->user_id,
'lecture_id' => $this->lecture_id,
'board_id' => $this->board_id,
'course_id' => $this->course_id,
'created_at' => $this->created_at,
'last_commented_at' => $this->last_commented_at,
]);
return $dataProvider;
}
}
这里有几点需要注意:
1. load()方法无法加载参数,那么需要注意一下,load()方法的第二个参数formname,load方法进行如下处理:
$this->load($params, '');
2 . 有时候,会有这种需求,即需要的dataProvider并不是通过已有的字段进行过滤获取,比如需要将记录按时间排序,我们不希望在 $query = VPost::find()之后进行orderby,这样处理会使所有的查询都会按照时间进行排序。
例如:在视图页有‘全部’和‘最新’两个选项卡,点击‘最新’时,将查询结果按照时间字段倒序排,实现方式如下:
第一步:视图层带参
//视图层‘最新’选项卡
echo Html::a( '最新', ['/crowdfund/default/index','newest'=>1] ); ?>
当点击时,newest参数就会通过下面的方法获取:
public function actionIndex()
{
$searchModel = new VCrowdfundSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
//这段代码,就是利用search类的search方法,将参数load进去,并进行过滤
但是虽然视图传递参数newest,但是search模型怎么识别呢?这就需要在search模型里定义该字段并加入rules规则中。
第二步:定义变量,并添加到rules方法中
public $newest;
加入rules方法
return [
[['id', 'target_amount','newest'], 'integer'],
[['title', 'description', 'syllabus'], 'string'],
];
第三步:变量newest判断,并过滤dataProvider
if($this->newest !== null){
$query->orderBy(['created_at'=> SORT_DESC]);
}
提示:可以利用这种方式,实现非常复杂的查询。在Yii框架中,所有的查询都应该通过search方法实现,除非你的需求非常特殊,特殊情况下可以实例化 ActiveDataProvider进行查询。