zoukankan      html  css  js  c++  java
  • 用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:xampphtdocsyii-1.1.14.f0fee9_201505frameworkwebjssource
     
    这个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属性并可以修改。这同样是我的初衷之一,下一步会去做。
     
     
     
  • 相关阅读:
    windows下搭建基于eclipse插件的GoLang开发环境
    vtk类之vtkImageReslice:基本算法,对体数据沿着轴进行切片
    vtk类之vtkTextureMapToSphere:纹理映射算法, 映射球体纹理
    wxpython 之 GDI 画刷Brush(三)
    c# 获取Rss数据
    C# 基础知识系列之面向对象基础
    SilverLight 得到文件绝对路径
    SilverLight C# 读取并修改App.config文件
    Silverlight 脱离浏览器
    C# 中New关键字的用法
  • 原文地址:https://www.cnblogs.com/anjo/p/5917616.html
Copyright © 2011-2022 走看看