【问题标题】:Filtering CGridView with CArrayDataProvider in Yii: how?在 Yii 中使用 CArrayDataProvider 过滤 CGridView:如何?
【发布时间】:2012-12-13 15:53:08
【问题描述】:

我在 Yii 中创建了一个 CGridView,它的行是从 XML 文件中读取的。我没有使用任何模型:只有一个控制器(我在其中读取文件)和一个视图(我在其中显示网格)。我无法在网格的第一行创建一个过滤器(每列一个输入字段),以便仅可视化某些行。我该怎么做?

这是我到现在为止的:

控制器:

<?php
class TestingController extends Controller {
    public function actionIndex() {
        $pathToTmpFiles = 'public/tmp';
        $xmlResultsFile = simplexml_load_file($pathToTmpFiles.'/test.xml');
        $resultData = array();
            foreach ($xmlResultsFile->result as $entry) {
                $chromosome = $entry->chromosome;
                $start = $entry->start;
                $end = $entry->end;
                $strand = $entry->strand;
                $crosslinkScore = $entry->crosslinkScore;
                $rank = $entry->rank;
                $classification = $entry->classification;
                $mutation = $entry->mutation;
                $copies = $entry->copies;
                array_push($resultData, array('Chromosome'=>$chromosome, \
                    'Start'=>$start,  'End'=>$end, Strand'=>$strand, \
                    'Crosslink_Score'=>$crosslinkScore,'Rank'=>$rank, \
                    'Classification'=>$classification, 'Mutation'=>$mutation, \
                    'Copies'=>$copies));
        }
        $this->render('index', array('resultData' => $resultData));
    }
}
?>

查看:

<?php
$dataProvider = new CArrayDataProvider($resultData, \
    array('pagination'=>array('pageSize'=>10,),));

$this->widget('zii.widgets.grid.CGridView', array( 'id' => 'mutationResultsGrid',
    'dataProvider' => $dataProvider, 'columns' => array(
        array(
           'name' => 'Chromosome',
           'type' => 'raw',
       ),
       array(
           'name' => 'Start',
           'type' => 'raw',
       ),
       array(
           'name' => 'End',
           'type' => 'raw',
       ),
       array(
           'name' => 'Strand',
           'type' => 'raw',
       ),
       array(
           'name' => 'Crosslink_Score',
           'type' => 'raw',
       ),
       array(
           'name' => 'Rank',
           'type' => 'raw',
       ),
       array(
           'name' => 'Classification',
           'type' => 'raw',
       ),
       array(
           'name' => 'Mutation',
           'type' => 'raw',
       ),
       array(
           'name' => 'Copies',
           'type' => 'raw',
       ),
    ),
));
?>

感谢您的帮助 麦芽酒

【问题讨论】:

    标签: php yii


    【解决方案1】:

    文件:FiltersForm.php(我把它放在 components 文件夹中)

    /**
     * Filterform to use filters in combination with CArrayDataProvider and CGridView
     */
    class FiltersForm extends CFormModel
    {
        public $filters = array();
    
        /**
         * Override magic getter for filters
         */
        public function __get($name)
        {
            if(!array_key_exists($name, $this->filters))
                $this->filters[$name] = null;
            return $this->filters[$name];
        }
    
        /**
         * Filter input array by key value pairs
         * @param array $data rawData
         * @return array filtered data array
         */
        public function filter(array $data)
        {
            foreach($data AS $rowIndex => $row) {
                foreach($this->filters AS $key => $value) {
                    // unset if filter is set, but doesn't match
                    if(array_key_exists($key, $row) AND !empty($value)) {
                        if(stripos($row[$key], $value) === false)
                            unset($data[$rowIndex]);
                    }
                }
            }
            return $data;
        }
    }
    

    在您的控制器中:

    ...
    $filtersForm = new FiltersForm;
    if (isset($_GET['FiltersForm'])) {
        $filtersForm->filters = $_GET['FiltersForm'];
    }
    $resultData = $filtersForm->filter($resultData);
    
    $this->render('index', array(
        'resultData' => $resultData,
        'filtersForm' => $filtersForm
    )}//end action
    

    最后需要 - 将过滤器添加到 CGridView 配置数组:

    ...
    'dataProvider' => $dataProvider,
    'enableSorting' => true,
    'filter' => $filtersForm,
    ...
    

    【讨论】:

      【解决方案2】:

      为什么不将xml中的信息存储到数据库中并使用YII ActiveRecord?

      在您的情况下,您需要一种实时机制来过滤每个过滤器查询的结果集。与 search() 方法一样,当您使用 YII ActiveRecord 模型时。

      因此,您可以在每次过滤器调用时在数组上使用带有回调的 array_filter() 之类的东西。 (编辑:或者这里使用的机制与 stripos 返回匹配的“行”:Yii Wiki

      或者,第二个选项,您可以使 xml 解析器依赖于您的过滤器输入,这对我来说感觉不太好:)。解析器必须解析每个过滤器输入,这可能是大 xml 文件的问题。

      或者,如前所述,将信息保存到数据库并使用标准 YII 机制。

      【讨论】:

      • 这不是他要求的
      【解决方案3】:

      假设您可以使用在 foreach 循环中的对象中获得的数据作为该特定列的过滤器,那么您可以将这些值传递给视图,例如:

      <?php
      class TestingController extends Controller {
          public function actionIndex() {
              $pathToTmpFiles = 'public/tmp';
              $xmlResultsFile = simplexml_load_file($pathToTmpFiles.'/test.xml');
              $resultData = array();
              foreach ($xmlResultsFile->result as $entry) {
                  ...
                  $chromosomeFilter[] = $entry->chromosome;
                  ...
              }
              $this->render('index', array(
                  'resultData'       => $resultData,
                  'chromosomeFilter' => $chromosomeFilter,
                  ...
              );
          }
      }
      ?>
      

      然后在该列的过滤器中使用该值;

      ...
      array(
          'name'   => 'Chromosome',
          'type'   => 'raw',
          'filter' => $chromosomeFilter,
      ),
      ...
      

      我没有测试过,它很大程度上取决于你的 xml 和 $entry-&gt;chromosome 的结构,但这可能有助于你走上正确的道路吗?

      【讨论】:

      • Mh.. 我想要实现的是这样的:imagebin.org/239196 我需要在网格的第一行有一行文本字段(过滤器),这样只有将显示其条目与您在过滤器中键入的文本匹配的行。您的解决方案似乎不起作用,我也无法从那里着手。
      • 您是否尝试将filter 选项添加到您的CGridView 实例? (而不是列,就像我在我的例子中所做的那样)
      • 但是用什么?如果我使用这个:$this-&gt;widget('zii.widgets.grid.CGridView', array( ... 'filter' =&gt; $chromosomeFilter, 'dataProvider' =&gt; $dataProvider, ... 我得到一个“对... yii/yii-1.1.6.r2877/framework/web/helpers/CHtml.php 中的非对象的成员函数getValidators() 的调用1735"
      • 我会推荐简单的设计。在这种情况下不要使用 CGridView ,您将面临处理关键问题的问题,最终我们不得不转向另一种选择。更多内容可以阅读yiiframework.com/forum/index.php/topic/9365-xml-as-data-source
      【解决方案4】:

      我遇到了同样的问题 而我所做的是实现http://www.datatables.net/ 并远程拉取数据。我将排序和分页传递给 javascript。

      【讨论】:

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