本文同樣實現 GridView 批次刪除,但強調 PJAX 容器整合、按鈕事件代理、Controller 交易處理與回饋訊息。程式碼結構更適合直接複製到 Gii 生成的 CRUD 視圖中。
'grid-pjax', 'timeout' => 5000, 'enablePushState' => false]);
echo GridView::widget([
'id' => 'grid', // 必須設定 id,供 JS 取得選取列
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\CheckboxColumn', 'name' => 'id', 'checkboxOptions' => ['class' => 'selection-ids']],
'id',
'title',
['attribute' => 'status', 'filter' => [0 => '禁用', 1 => '啟用']],
['class' => 'yii\grid\ActionColumn', 'template' => '{view} {update} {delete}'],
],
]);
// 批次刪除按鈕 (放在 PJAX 容器內,重載後事件自動重綁)
echo Html::button('批次刪除', [
'id' => 'btn-batch-delete',
'class' => 'btn btn-danger btn-batch-delete',
'data-confirm' => '確定要刪除選中的資料嗎?',
'data-url' => \yii\helpers\Url::to(['batch-delete']),
]);
Pjax::end();
// JS 註冊 (使用事件代理,PJAX 重載後仍有效)
$this->registerJs(<<
response->format = \yii\web\Response::FORMAT_JSON;
$ids = \Yii::$app->request->post('ids', []);
if (!is_array($ids) || !$ids) {
return ['success' => false, 'message' => '無效的 ID 列表'];
}
// 權限檢查 (範例)
if (!\Yii::$app->user->can('articleBatchDelete')) {
return ['success' => false, 'message' => '權限不足'];
}
$transaction = \Yii::$app->db->beginTransaction();
try {
$deleted = \app\models\Article::deleteAll(['id' => $ids]);
$transaction->commit();
return ['success' => true, 'deleted' => $deleted];
} catch (\Exception $e) {
$transaction->rollBack();
\Yii::error($e->getMessage());
return ['success' => false, 'message' => '伺服器錯誤: ' . $e->getMessage()];
}
}
?>
| 細節 | 本文做法 | 作用 |
|---|---|---|
| GridView id | 'id' => 'grid' | JS $('#grid').yiiGridView('getSelectedRows') 依賴此 id |
| CheckboxColumn name | 'name' => 'id' | 對應主鍵欄位,取得的 keys 即為 id 陣列 |
| 按鈕放在 PJAX 內 | Pjax::begin ... Pjax::end 包裹 | 重載後按鈕 DOM 更新,事件代理 $(document).on 自動生效 |
| URL 由 data-url 提供 | 'data-url' => Url::to(['batch-delete']) | 避免 JS 硬編碼路由,利於維護 |
| 確認對話框 | 'data-confirm' + JS confirm() | 雙重確認,防誤刪 |
| 交易包裹 | db->beginTransaction() ... commit/rollBack | 保證原子性,部分失敗全數回滾 |
| JSON 回應 | Response::FORMAT_JSON | 前端統一處理成功/失敗 |
Article::updateAll(['is_delete' => 1, 'deleted_at' => time()], ['id' => $ids]);admin_log 表 (用戶、動作、IP、影響 ID)。