Yii2中点击公司名称展示对应员工联系人的实现方法问询
针对你在Yii2项目里的需求,我整理了几种常用的实现方式,你可以根据交互需求来选择:
场景回顾
你有companies和contacts两张表,想要点击companies GridView中的公司名称时,获取并展示该公司的员工联系人数据,对应SQL:select * from contacts where company_id = $id。你的现有代码是companies/index.php里的GridView配置。
方法1:跳转到联系人列表页面(最直接简单)
这种方式是把公司名称做成链接,点击后跳转到联系人的列表页,同时传递company_id参数来过滤数据。
修改GridView的name列配置
把原来的'name'替换成下面的列配置:
[ 'attribute' => 'name', 'format' => 'raw', 'value' => function ($model) { // 生成指向contacts/index的链接,携带当前公司的company_id return Html::a($model->name, ['contacts/index', 'company_id' => $model->company_id], [ 'title' => '查看该公司所有联系人', 'class' => 'text-primary' ]); }, ],
注意:确保你已经引入了
yii\helpers\Html类(通常在视图顶部会有use yii\helpers\Html;)
处理ContactsController的index动作
在ContactsController.php的actionIndex方法里,接收并使用company_id参数过滤数据:
public function actionIndex($company_id = null) { $searchModel = new ContactsSearch(); $queryParams = Yii::$app->request->queryParams; // 如果传递了company_id,自动添加过滤条件 if ($company_id) { $queryParams['ContactsSearch']['company_id'] = $company_id; } $dataProvider = $searchModel->search($queryParams); return $this->render('index', [ 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, ]); }
确保ContactsSearch支持company_id过滤
打开ContactsSearch.php,在rules()方法里添加company_id的规则:
public function rules() { return [ // 其他已有的规则... [['company_id'], 'integer'], ]; }
然后在search()方法里添加对应的过滤条件:
$query->andFilterWhere([ // 其他已有的条件... 'company_id' => $this->company_id, ]);
方法2:使用AJAX弹窗加载联系人(更友好的交互)
如果不想跳转到新页面,可以用Yii2的Modal组件,点击公司名称后通过AJAX把联系人数据加载到弹窗里展示。
步骤1:修改GridView的name列
[ 'attribute' => 'name', 'format' => 'raw', 'value' => function ($model) { return Html::a($model->name, '#', [ 'title' => '查看该公司联系人', 'class' => 'company-name-modal-trigger', 'data-company-id' => $model->company_id ]); }, ],
步骤2:在页面底部添加Modal组件
在companies/index.php的末尾(GridView之后)添加Modal:
<?php use yii\bootstrap4\Modal; // 如果你用的是bootstrap3,改成yii\bootstrap\Modal Modal::begin([ 'id' => 'contacts-modal', 'title' => '<h5>公司联系人列表</h5>', 'size' => Modal::SIZE_LARGE, 'footer' => Html::button('关闭', ['class' => 'btn btn-secondary', 'data-dismiss' => 'modal']) ]); // 弹窗内容容器,AJAX加载的内容会放到这里 echo '<div id="contacts-modal-body"></div>'; Modal::end(); ?>
步骤3:添加JavaScript处理点击事件
在Modal后面添加JS代码(可以放在<script>标签里,或者引用外部JS文件):
$(document).on('click', '.company-name-modal-trigger', function(e) { e.preventDefault(); // 阻止默认链接行为 const companyId = $(this).data('company-id'); // 发起AJAX请求获取联系人列表的HTML $.get('<?= Yii::$app->urlManager->createUrl(['contacts/list-by-company']) ?>', { company_id: companyId }, function(response) { $('#contacts-modal-body').html(response); $('#contacts-modal').modal('show'); // 显示弹窗 } ); });
步骤4:在ContactsController里添加专用动作
创建一个返回联系人列表HTML的动作,不需要完整布局:
public function actionListByCompany($company_id) { $searchModel = new ContactsSearch(); // 直接传入company_id过滤条件 $dataProvider = $searchModel->search(['ContactsSearch' => ['company_id' => $company_id]]); // 用renderAjax渲染,不带布局,只返回GridView部分 return $this->renderAjax('_contacts_list', [ 'dataProvider' => $dataProvider, ]); }
步骤5:创建联系人列表的局部视图
在views/contacts目录下新建_contacts_list.php,只渲染GridView:
<?php use yii\grid\GridView; echo GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ ['class' => 'yii\grid\SerialColumn'], 'first_name', 'last_name', 'email', // 添加你需要展示的其他联系人字段 ], ]);
方法3:在当前页面下方加载联系人列表
如果希望在同一个页面展示联系人,点击公司名称后在GridView下方显示对应列表,可以参考这种方式:
步骤1:修改GridView的name列(和方法2类似)
[ 'attribute' => 'name', 'format' => 'raw', 'value' => function ($model) { return Html::a($model->name, '#', [ 'class' => 'company-name-load-contacts', 'data-company-id' => $model->company_id ]); }, ],
步骤2:在页面添加联系人容器
在GridView下方添加一个用于展示联系人的容器:
<div id="contacts-section" style="margin-top: 30px; display: none;"> <h3 class="mb-3">当前公司联系人</h3> <div id="contacts-list-container"></div> </div>
步骤3:添加JS代码加载内容
$(document).on('click', '.company-name-load-contacts', function(e) { e.preventDefault(); const companyId = $(this).data('company-id'); $.get('<?= Url::to(['contacts/list-by-company']) ?>', { company_id: companyId }, function(response) { $('#contacts-list-container').html(response); $('#contacts-section').show(); // 显示联系人区域 } ); });
这里同样可以复用方法2里的
actionListByCompany和_contacts_list.php视图
内容的提问来源于stack exchange,提问作者Goli

