我有以下方法,它通过查询来搜索我的笔记:
function search( $q = null )
{
if ( $q == null )
{
$this->redirect(array('action' => 'index'));
}
$this->paginate = array(
'limit'=>5,
'order'=>'Note.datetime DESC',
'conditions' => array(
'OR' => array(
'Note.title LIKE' => '%'. $q . '%',
'Note.content LIKE' => '%'. $q . '%'
)
),
'Note.status'=>1
);
$this->set('notes', $this->paginate());
$this->render('index');
}
正如您所看到的,它使用一个名为"q"的参数来查询模型数据。
我已经把这个连接到路由器上了,就像这样:
Router::connect('/notes',
array('controller'=>'notes','action'=>'index', 'page' => 1),
array(
'pass' => array('page')
)
);
Router::connect('/notes/page/:page',
array('controller' => 'notes', 'action' => 'index'),
array(
'pass' => array('page'),
'page' => '[1-9]+'
)
);
Router::connect('/notes/search/:page/:q',
array('controller'=>'notes','action'=>'search', 'page' => 1),
array(
'pass' => array('page','q')
)
);
Router::connect('/notes/search/:q/page/:page',
array('controller' => 'notes', 'action' => 'search'),
array(
'pass' => array('page','q'),
'page' => '[1-9]+'
)
);
通过这种方式,我应该获得如下URL:
domain.com/notes - loads page 1 of notes
domain.com/notes/page/2 - loads page 2 of notes
domain.com/notes/search/Hello - searches for Hello in notes
domain.com/notes/search/Hello/page/2 - shows page 2 of the above search
视图中的寻呼机看起来像:
<?php if(isset($this->request->params['named']['q'])) { ?>
<?php $this->Paginator->options(array('url'=>array('controller' => 'notes', 'action' => $action, 'q' => $this->request->params['named']['q']))); ?>
<?php } else { ?>
<?php $this->Paginator->options(array('url'=>array('controller' => 'notes', 'action' => $action))); ?>
<?php } ?>
它适用于索引方法,但对于搜索方法,它会变得混乱,因为当我进行搜索时,它没有像预期的那样将寻呼机与路线匹配。例如,我得到了类似domain.com/notes/search/2/:q
的URL
此外,我真的不喜欢必须将分页器选项包装在if语句中,所以如果我能让它自动计算出url,那将是非常棒的,因为这样做很麻烦,而且似乎是上述问题的原因。
我已经在路由器的顶部连接了命名参数,如下所示:
Router::connectNamed(array('q'));
最后,我选择使用POST而不是GET来进行搜索,这样一切都可以在服务器端处理,而不是用混乱的url重写和聪明的方法。
这是我把表格做成的样子:
<?php echo $this->Form->create('search', array('url'=>array('controller'=>'notes','action'=>'search'),'class'=>'search')); ?>
<label class="placeholder" for="q">Search</label>
<?php if( isset($q) ) { $term = $q; } else { $term = ''; } ?>
<?php echo $this->Form->input('q', array('label'=>false,'id'=>'q','value'=>$term)); ?>
<button type="submit" class="btn ss-icon ss-search"></button>
<?php echo $this->Form->end(); ?>
搜索方法:
function search()
{
if ($this->request->is('post')) {
$this->Session->write('q', $this->request->data['search']['q']);
$this->redirect(array('action' => 'search'));
} else {
$q = $this->Session->read('q');
$this->paginate = array(
'limit'=>5,
'order'=>'Note.datetime DESC',
'conditions' => array(
'OR' => array(
'Note.title LIKE' => '%'. $q . '%',
'Note.content LIKE' => '%'. $q . '%'
)
),
'Note.status'=>1
);
$this->set('q',$q);
$this->set('action','search');
$this->set('notes', $this->paginate());
$this->render('index');
}
}
路线:
Router::connect('/notes/search',
array('controller'=>'notes','action'=>'search', 'page' => 1),
array(
'pass' => array('page')
)
);
Router::connect('/notes/search/page/:page',
array('controller' => 'notes', 'action' => 'search'),
array(
'pass' => array('page'),
'page' => '[1-9]+'
)
);
如果在AppController中使用了搜索方法以外的任何其他页面,我会清理会话:
if(strpos($this->here, Router::url(array('controller'=>'notes','action'=>'search'))) === 0 ) {
//echo 'yes';
} else {
$this->Session->delete('q');
}
这给了我类似的网址:
domain.com/notes
-加载钞票第1页
domain.com/notes/page/2
-加载钞票第2页
domain.com/notes/search
-在笔记(存储在会话中)中搜索Hello
domain.com/notes/search/page/2
-显示上述搜索的第2页