【问题标题】:Yii - CGridViewYii - CGridView
【发布时间】:2012-11-01 00:12:28
【问题描述】:

我正在使用 Yii (v1.1.12) 编写我的第一个应用程序,我的学习曲线有点陡峭,所以我需要一些帮助。

想象以下表格(及其关系):

  • 详细 (n:1) 文档
  • 文档 (n:1) 用户
  • 用户 (n:1) 部门
  • 文档 (n:1) 类别

user 是保存有关可以登录和使用应用程序的用户信息的表。

我已经设法组合(使用 Gii 和修改)一个列出所有文档的视图,并且还设法在网格中显示类别名称而不是类别 ID。

我想要实现的功能之一是允许用户切换视图,以便 (a) 仅列出与登录用户相关的文档,或 (b) 仅列出与其部门相关的文档。

我环顾四周,没有运气。有人可以帮忙吗?

干杯, 乔治

更新:当前我使用zii.widgets.grid.CGridView 显示文档列表。

更新 2: 在 Omar 对CDbCriteria 的引用之后,我找到了this URL,其中包含有关该主题的更多详细信息。

我想出了以下模型代码,效果很好:

public function searchByUser($user_id)
{
   $criteria=new CDbCriteria;
   $criteria->condition = " user_id = ".$user_id;
   return new CActiveDataProvider($this, array(
          'criteria'=>$criteria,
   ));
}
public function searchByDepartment($user_id)
{
   $criteria=new CDbCriteria;
   $criteria->alias="p";
   $criteria->join = "JOIN (SELECT u.id 
                              FROM user u 
                             INNER JOIN user uu 
                                ON u.department_id = uu.department_id 
                             WHERE uu.id = ".$user_id.") uu 
                                ON p.user_id = uu.id";                  
    return new CActiveDataProvider($this, array('criteria'=>$criteria,));
}

虽然上述工作按预期工作,但我希望有一个根本不需要我编写切碎的 SQL 代码的解决方案。不是因为懒惰,而是为了利用框架的更多功能。

我只是觉得这种方法没有遵循最佳实践 (?)。

【问题讨论】:

  • 您目前如何在您的视图中列出文档?你是在使用 CGridView / CListView / 还是其他方法?
  • 我编辑了我的问题以澄清这一点。

标签: php yii cgridview


【解决方案1】:

尝试创建您自己的CDBCriteria 并在其中定义任何条件,并将其作为数据提供者传递给您的网格视图。

如果您允许在 网格视图 内进行搜索,请将条件传递给搜索函数,并在其中将传递的条件与搜索内的条件合并。

【讨论】:

  • 这是我尝试的第一个方法。它工作得很好,但导致了一个“更胖”的模型。不完全相信。会尝试替代方案,但如果不能让其他东西起作用,会回到这个。
【解决方案2】:

您可以使用关系来实现您所追求的。例如,要查看某个用户的所有文档和部门,您首先需要为该用户设置relations,在您的情况下,您可以像这样设置您的用户模型;

public function relations()
{
    return array(
        'documents' => array(self::HAS_MANY, 'Document', 'user_id'),
        'department' => array(self::HAS_ONE, 'Department', 'department_id'),
    );
}

然后您可以像这样为当前用户拉取所有文档:

$user = User::model()->findByPk($userId);
$documents = $user->documents;

$documents 将成为所有用户文档的活动模型数组。

要获取该用户部门的所有文档,有几个选项。您可以再次使用关系,向 Department 模型添加以下内容:

public function relations()
{
    return array(
        'users' => array(self::HAS_MANY, 'User', 'department_id'),
        'documents' => array(self::HAS_MANY, 'Document', 'document_id', 'through'=>'users'),
    );
}

这应该使您能够像这样提取所有部门的文档;

$department = Department::model()->findByPk($departmentId);
$documents = $department->documents;

这反过来意味着您可以像这样获取用户部门文档:

$user = User::model()->findByPk($userId);
$documents = $user->department->documents;

很可能有一种更有效的方法可以通过在用户模型中使用关系来获取这些内容,但我现在做我们现在的工作为时已晚;)

一旦您拥有一组活动记录模型,您就可以随时使用CArrayDataProvider 将它们传递给数据提供者,就像这样;

$dataprovider = new CArrayDataProvider($documents);

顺便说一句,我还没有测试过任何一个,所以他们可能需要一些编辑!

【讨论】:

  • 这种方法对我来说似乎更“自然”,至少我不必到处散布 SQL 代码片段 :) 这两种方法中哪一种更有效?跨度>
  • @GeorgeG 我认为这实际上可能对您有所帮助,将 CDbCriteria 与 CActiveDataProvider 一起使用:YII CActiveDataProvider with relational tables
  • 我稍后会尝试并报告。
【解决方案3】:

您需要在适当的模型上修改search 函数(我猜是documents)。您已经可以在其中看到可以使用的代码。

给搜索函数本身添加一些参数,可以从控制器传入。然后使用这些来确定要进行哪些compare 调用。

【讨论】:

  • 这与奥马尔的回答没有太大区别。我更喜欢 Omar 的回答,因为我使用了对 CDbCriteria 的引用来进一步搜索。
猜你喜欢
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多