用YII实现多重查询(基于tag)
生活随笔
收集整理的這篇文章主要介紹了
用YII实现多重查询(基于tag)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
場景: 有一個飯店表 restaurant,存放所有飯店記錄。我需要一個功能,將飯店按照不同的條件進行多重查詢。就象這樣: 氛圍:浪漫 / 商務會談 / 茅草屋 菜系:川菜 / 魯菜 / 家常菜... 區域:東區 / 西區 / 南區 / 北區... 我點擊一個或多個條目,則下方自動刷出符合條件的飯店來。 例如我點擊了 浪漫、商務會談、魯菜,由于浪漫、商務會談是同屬于氛圍的,應該認為用戶想查找的是“或”的關系,不管出現二者的哪一個,都屬于查詢范圍;而魯菜是屬于菜系的,那么與前兩個條件來說,應該是“與”的關系,即:用戶想查(氛圍==浪漫 || 氛圍==商務會談)&& (菜系==魯菜)的所有飯館的集合。 這里有一個邏輯上的小別扭:如果我氛圍選了浪漫,菜系不選,那么是不是要選擇(氛圍==浪漫)&& (菜系==none)嗎?這樣的結果肯定為空。實際上,不選菜系表示對菜系無要求,所以范圍應該是(氛圍==浪漫)&& (菜系==所有)。 考慮到這個功能比較常見,打算做一個通用的東西出來 感覺這是個難度比較大的功能,來做一下吧。 1、建立幾個表:tag_tablename、tag_title、tag_text、tag_refer。其中 tag_tablename - 在這里只有一條記錄 restaurant,但將來可能會有其它的,如article、user等 tag_title - 這是大的分類,分別為氛圍、菜系、區域,每一條的tablename_id為1,即restaurant tag_text - 這是具體的tag,如浪漫、川菜、魯菜、東區。。等等 tag_refer - 這是一個多對多的表,它記錄了restaurant表中的記錄與tag_text表中的記錄的多對多的對應關系 2、創建 Model。這里,TagTablename里實現了tag_titles,TagTitle里面實現了tag_texts。 3、寫實現的類 CAnjoTag // 生成:// 氛圍:浪漫 / 商務會談 / 茅草屋...// 菜系:川菜 / 魯菜 / 家常菜...// 區域:東區 / 西區 / 南區 / 北區...// 這樣的樣式,并且最好能接受點擊,并且最好在點擊后調用ajax更新下面的查詢結果public static function tag_list($tablename, $options=array()) {$r=' <ul class="select">';。。。return $r;}
?
這里面的具體實現就不貼出來了,主要是一步步生成html代碼,顯示前面的那些內容,并接受點擊,點擊一次選擇,再次點擊則取消選擇。點擊會觸發一個javascript函數,它回調另一個javascript函數,用以 Ajax 方式更新查詢區域的內容。 然后,這樣調用和更新ajax獲取的內容 <?php echo CAnjoTag::tag_list('Restaurant', array('click_callback'=>'tag_clicked')); ?> <script> function tag_clicked(ids) {// console.log(ids);$('#rest-grid').load('?r=rest/ajaxAction&action=rest_query', {tagtext_ids: ids}); } </script> 在RestController中這樣實現: public function actionAjaxAction($action){$r='';switch ($action){case 'rest_query':$ids=Yii::app()->request->getParam('tagtext_ids');if (substr($ids, -1)==',') $ids=substr($ids, 0, -1); //刪除結尾的 ,$ids=trim($ids);if ($ids!=''){$cond="id in (select record_id from {{tag_refer}} where tag_text_id in ($ids))";$criteria = new CDbCriteria;$criteria->condition=$cond;$count = Restaurant::model()->count($criteria);$pager = new CPagination($count);$pageSize=10;$pager->params = array('tagtext_ids'=>$ids, 'action'=>'rest_query');//分頁中添加其他參數$pager->pageSize=$pageSize;$pager->applyLimit($criteria);$dataProvider=new CActiveDataProvider('Restaurant', array('criteria'=>$criteria,'sort'=>array('defaultOrder'=>'id desc',),'pagination'=>$pager,));$this->renderPartial('_query_result', array('dataProvider'=>$dataProvider));die();}break;}echo $r;} 4、ajax換頁問題 調試ajax換頁時費了很大勁。總是做不到按Ajax方式顯示下一頁,一點頁碼的鏈接就跳到新頁上了。看一下console的錯誤信息,不能ajax調用的原因是在 jquery.yiigridview.js 中,出現了錯誤: $.param.querystring is not a function 網上解釋說:這個錯誤會導致你無論怎么選擇filter,都不會發送請求道cintroll去取數據,解決辦法就是,無論在什么地方調用jquery,最好使用Yii的registe來注冊,而不要使用<script>來引入. <?php Yii::app ()->clientScript->registerCoreScript ( 'jquery' ); ?> 但bootstrap提示, Uncaught Error: Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3 于是找到 Yii的核心script所在的位置: D:\xampp\htdocs\yii-1.1.14.f0fee9_201505\framework\web\js\source 這個jquery.js 是1.8.3的,我復制了一個1.11.3的進來,一切正常了。 這個jquery的問題,真的要改變習慣了。以前也會因為jquery的多次引用而造成類似的這種莫名其妙的錯誤,試著改變jquery的位置或顯式地引用一下它,有時也能解決,但終歸不是正途。 (另:看了 jquery.yiigridview.js的源碼,原來是Yii的作者寫的。真牛~前端也很強嘛) 5. 待改進: 在actionAjaxAction中,$cond="id in (select record_id from {{tag_refer}} where tag_text_id in ($ids))"; 這個寫法是不嚴謹的。它把所有的條件都當做“或”來處理了,沒有實現前面分析的結論。這是小問題,以后再細細實現。 另一個是,在飯店信息的修改界面,我需要調用 CAnjoTag 的另一個方法,顯示飯店的相關tag屬性并可以修改。這同樣是我的初衷之一,下一步會去做。轉載于:https://www.cnblogs.com/anjo/p/5917616.html
總結
以上是生活随笔為你收集整理的用YII实现多重查询(基于tag)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spark RDD概念学习系列之rdd持
- 下一篇: PHP两种不同的快递运单号查询