场景:
有一个饭店表 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属性并可以修改。这同样是我的初衷之一,下一步会去做。
 
 
 

最新文章

  1. C#删除datable空行
  2. php获取checkbox复选框的内容
  3. Leetcode 160 Intersection of Two Linked Lists 单向链表
  4. M方法和D方法的区别
  5. C#获取文件的绝对路径
  6. unity中js脚本与c#脚本互相调用
  7. python种的builtin函数详解-第三篇
  8. [置顶] 强制访问控制内核模块Smack
  9. 细说php(六) 数组
  10. CSS background 属性 总结
  11. bettercap实现内网Dns欺骗
  12. Qt滑动条设计与实现
  13. .net core中使用autofac进行IOC
  14. C++入门之初话多态与虚函数
  15. 微信小程序城市定位(百度地图API)
  16. Android的组件化和模块化
  17. Haskell语言学习笔记(90)Default
  18. plsql 执行批量文件
  19. android WebView中js的alert()失效
  20. Discuz论坛post登录C#源码

热门文章

  1. 【219】◀▶ IDL 数学函数说明
  2. RetHad6.7离线通过.rpm安装
  3. HDOj-1425
  4. Lua 不是 C++
  5. VS中用C#开发应用程序的调试入门、技巧和实例(转载)
  6. 洛谷 - P3377 - 【模板】左偏树(可并堆) - 左偏树 - 并查集
  7. [Xcode 实际操作]二、视图与手势-(6)给图像视图添加阴影效果
  8. 15.split分割注意事项
  9. iOS 7 隐藏特性
  10. VRTK3.3.0-001头盔相机