【问题标题】:Search form and inline cGridView filter inter-operationability搜索表单和内联 cGridView 过滤器的互操作性
【发布时间】:2013-02-04 23:52:22
【问题描述】:

我会保持这个非常抽象,因为我相信(希望)这是一个容易解决的普遍问题。 我修改了一个 gii 生成的管理页面,如下所示。 修改搜索表单以选择属于给定用户的记录。这有效,并且在搜索网格时更新正常。

我已经定制了网格的输出以包含各种用户相关的数据,例如每条记录都反映了一些用户数据。

当我使用网格过滤器(到小部件的顶部)时,过滤器结果很好,但是我失去了用户的原始过滤器。

因此,我查询用户并选择一些结果,当我想根据其他条件过滤这些结果时,它会生成从整个数据集生成的结果,而不是用户过滤的结果。

附注,我已经尝试安装http://www.yiiframework.com/extension/remember-filters-gridview/

这实际上会产生一些结果,因为当我按照上面指定的过滤器进行过滤时,它不起作用,但是当我刷新页面时,结果完全符合预期,因为它保存了上一个会话中的两个过滤器。

希望这很清楚, 请帮忙! 谢谢

【问题讨论】:

    标签: php yii cgridview


    【解决方案1】:

    代码总是很有帮助,但如果我理解正确,我会做类似的事情来显示用户消息;我设置了一个初始过滤器以仅查找发送给登录用户的消息,然后我还需要让用户按主题和发件人过滤消息。我不知道你的模型或标准的名称,所以这里有一个简化的例子来说明我是如何做到的:

    控制器:

    public function actionIndex()
    {
        $model = new Message('search');
        $model->unsetAttributes();
    
        if(isset($_GET['Message']))
            $model->attributes = $_GET['Message'];
    
        // Set default filter
        $model->msg_to = Yii::app()->user->id;
    
        $this->render('index', array('model' => $model));
    }
    

    查看:

    $this->widget('zii.widgets.grid.CGridView', array(
        'id'=> 'message-grid',
        'dataProvider'=> $model->search(),
        'filter'=> $model,
    ));
    

    型号:

    public function search()
    {
        $criteria = new CDbCriteria;
    
        $criteria->compare('from',$this->from);
        $criteria->compare('msg_to',$this->msg_to);
        $criteria->compare('from_name',$this->from_name,true);
        $criteria->compare('subject',$this->subject,true);
        $criteria->compare('body',$this->body,true);
        $criteria->compare('read',$this->read);
    
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
            'pagination'=>array('pageSize'=>15),
        ));
    }
    

    如果您的默认过滤条件相当复杂,最好的办法是在模型中创建一个named scope,如下所示:

    public function scopes()
    {
        return array(
            'inbox' => array(
                'condition' => 't.msg_to = :user_id',
                'params' => array(':user_id' => Yii::app()->user->id),
                'order' => 'min(t.read) ASC, t.posted_on DESC',
            ),
        );
    
    }
    

    要使用该范围,您可以在 CGridView 中写入 $model->inbox()->search() 而不是 $model->search() 然后,您还应该删除 $model->msg_to = Yii::app()->user->id;

    最后一件事:如果您的标准需要用户输入,例如通过 $_GET 变量,您可以使用“Parameterized Named Scopes”。请参阅此页面上的部分:http://www.yiiframework.com/doc/guide/1.1/en/database.ar#named-scopes 您将以相同的方式使用它们:$model->inbox()->search()

    【讨论】:

      【解决方案2】:

      根据您的代码条件,答案可能会有所不同:

      1) user_id 的形式是 GET 还是 POST?如果是 POST,则必须更改为 GET,因为 .CGridView 用于 GET

      2) 请记住,我们正在使用两个单独的表单,因此,如果在每种情况下都收到执行操作所需的参数,您必须验证您的代码...如果没有,您必须更改 URL 或会话或 cookie 以始终接收您需要的所有数据。

      3) CgridView 将过滤器添加到当前 url 并发送 AJAX,我猜想选择 user_id 的表单是普通的 HTTP GET(不适用于 AJAX),用于检索用户 ID 的表单字段的名称是user_id

      a) 过滤器字段被命名为 CGridView "model_name['attribute_name']" 然后在控制器中:

      public function actionAdmin($user_id="") {
          ...
          if (!empty($user_id)) $model->user_id = intval($user_id);
          if (isset($_GET['model_name'] ) $model->attributes = $_GET['model_name'];
          ...
      }
      

      b) 如果表单中的用户 ID 也可用作 CGridWiew 列,则:

      public function actionAdmin($user_id="") {
         ...
         if (isset($_GET['model_name'] ) {
             if (! isset($_GET['model_name']['user_id']) && ! empty($user_id) ) {
                $_GET['model_name']['user_id'] = $user_id;
             }          
              $model->attributes = $_GET['model_name'];
         } elseif (!empty($user_id)) $model->user_id = intval($user_id);
         ... 
      }
      

      c) 是你的 actionAdmin 就像 actionAdmin() 你必须检索用户 ID

      yii::app()->request->getParam('user_id');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-15
        • 1970-01-01
        相关资源
        最近更新 更多