4 个关注者

收集表格输入

有时您需要在单个表单中处理多个相同类型的模型。例如,多个设置,每个设置都存储为一个名称-值对,并由一个 Setting 活动记录 模型表示。这种类型的表单也经常被称为“表格输入”。与之相反,处理不同类型的不同模型,在部分 具有多个模型的复杂表单 中处理。

以下展示了如何使用 Yii 实现表格输入。

有三种不同的情况需要涵盖,它们需要以略微不同的方式处理

  • 更新数据库中的一组固定记录
  • 创建一组动态的新记录
  • 在一个页面上更新、创建和删除记录

与之前解释的单一模型表单相比,我们现在正在处理模型数组。此数组被传递到视图以以表格样式显示每个模型的输入字段,我们将使用 yii\base\Model 的辅助方法,这些方法允许一次加载和验证多个模型

更新一组固定记录

让我们从控制器操作开始

<?php

namespace app\controllers;

use yii\web\Controller;
use app\models\Setting;

class SettingsController extends Controller
{
    // ...

    public function actionUpdate()
    {
        $settings = Setting::find()->indexBy('id')->all();

        if ($this->request->isPost) {
            if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) {
                foreach ($settings as $setting) {
                    $setting->save(false);
                }
                return $this->redirect('index');
            }
        }

        return $this->render('update', ['settings' => $settings]);
    }
}

在上面的代码中,我们使用 indexBy() 从数据库中检索模型以填充由模型主键索引的数组。这些将在稍后用于识别表单字段。 Model::loadMultiple() 使用来自 POST 的表单数据填充多个模型,而 Model::validateMultiple() 一次验证所有模型。由于我们在使用 validateMultiple() 之前已经验证了我们的模型,因此我们现在将 false 作为参数传递给 save() 以避免两次运行验证。

现在是 update 视图中的表单

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin();

foreach ($settings as $id => $setting) {
    echo $form->field($setting, "[$id]value")->label($setting->name);
}

echo Html::submitButton('Save');

ActiveForm::end();

这里,我们为每个设置渲染了一个名称和一个具有值的输入。为输入名称添加适当的索引很重要,因为这是 Model::loadMultiple() 确定使用哪些值填充哪个模型的方式。

创建一组动态的新记录

创建新记录类似于更新,除了我们实例化模型的部分

public function actionCreate()
{
    $settings = [];
    if ($this->request->isPost) {
        $count = count($this->request->post($setting->tableName()));
        for ($i = 0; $i < $count; $i++) {
            $settings[$i] = new Setting();
        }
        if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) {
            foreach ($settings as $setting) {
                $setting->save(false);
            }
            return $this->redirect('index');
        }
    }
    $settings[] = new Setting();

    return $this->render('create', ['settings' => $settings]);
}

我们在这里创建了一个初始的 $settings 数组,默认情况下包含一个模型,这样至少一个文本字段在视图中始终可见。此外,我们还为我们可能接收到的每一行输入添加了更多模型。

在视图中,您可以使用 JavaScript 动态添加新的输入行。

在一个页面上组合更新、创建和删除

注意:本节正在开发中。

它还没有内容。

待定

发现错别字或您认为此页面需要改进?
在 github 上编辑它 !