Yii2 和默认值为 NULL 的浮点字段

Yii2 and float field with default value NULL

official documentation 示例 "Country" 数据库中。我决定为国家添加新字段 (属性),即 area。我在 MySQL 数据库的 table 中添加了一个名为 country 的字段,名称为 area,结构如下:

`area` float DEFAULT NULL

数据库中新字段的值采用默认值 0,在视图中显示为 0.00,如以下屏幕截图所示:

在更新表单中,我为 area 添加了一个输入字段,如下所示:

// In views/country/_form.php, I added the following line to the form:
<?= $form->field($model, 'area')->textInput() ?>



 //In models/Country.php, I did not set any validation rules for area field.
public function attributeLabels()
    {
        return [
            'code' => 'Code',
            'name' => 'Name',
            'population' => 'Population',
            'area' => 'Area in KM<sup>2</sup>'
        ];
    }

现在更新视图中的所有字段都已成功更新,除了新字段 area。简单地说,如果没有任何错误消息,它根本不会更新。 为什么?

此外,如屏幕截图所示,在视图中 area 标签被正确打印出来,但是,在更新视图中它显示为它的 HTML 实体,即 Area in KM<sup>2</sup>为什么?

另一方面,我不喜欢非定义区域国家的面积显示0.00,所以我决定把它变成N/A所以我在[=57中做了以下回调方法=].php:

public function afterFind()
    {
      if ($this->area == NULL){         
         $this->area = 'N/A';       
      }   
      return true;
    }

但是,上述解决方案在操作视图中产生错误:

'N/A' is not a numeric value.

因此,我将 N/A 替换为 NULL,并且视图操作工作正常,并在视图中使用 (not set) 而非 0.00 分配了非定义区域国家/地区。 这里的最后一个问题, 有什么方法可以为未定义区域的国家/地区制作视图打印输出 N\A?动作视图使用 DetailView::widget

Now all fields in update view, are updated successfully, except the new field area. It, simply, does not updated at all without any error messages. Why?

因为它不是安全属性。你说它没有出现在规则中。如果你不想验证它,但希望能够大量分配它,你应该在验证规则中明确指定它,如下所示:

['area', 'safe'],

在官方文档中阅读有关模型 safe attributes 的更多信息。

Also, as the screen shot shows, in the view area label is printed out correctly, however, in the update view it shows as its HTML entity i.e Area in KM<sup>2</sup>. Why?

这就是属性标签在 DetailView 中的呈现方式:

https://github.com/yiisoft/yii2/blob/master/framework/widgets/DetailView.php#L206

并且在 Html::activeLabel() 中被 ActiveForm's 使用 field():

https://github.com/yiisoft/yii2/blob/master/framework/helpers/BaseHtml.php#L1048

如果未明确指定并自动取自 attributeLabels(),则无论选项如何,编码都会应用。

作为 ActiveForm 中的解决方法,我建议像这样传递它:

<?= $form->field($model, 'area')->label('Area in KM<sup>2</sup>') ?>

我认为复制这样的内容没什么大不了的,因为它不是代码逻辑,很少更改。即使它会改变,也很容易在您的编辑器中用全局搜索替换它。如果你强烈反对,也许最好在你的模型中额外声明它。

如果需要,您可以在 Github 上创建问题。也许我错过了一些东西,但我没有找到禁用 ActiveForm.

中标签编码的方法

另一种解决方法是简单地将 html 替换为文本表示,例如 square km. 它有点长,但编码没有这个问题。

The last question here, is there any way to make the view printout N\A for non defined area countries?

我认为你在afterFind()中做的不好,因为你用显示值替换了实际模型值。它可以在其他地方使用,例如在更新过程中并导致一些错误。

您至少可以在您认为有两个选项的情况下完成。

1)如果空值只出现在area,或者你想显示N\A其他属性null值同样,您可以像这样简单地替换默认的 null 表示:

use Yii;

...

Yii::$app->formatter->nullDisplay = 'N\A';

您应该在渲染之前放置此代码 DetailViewofficial documentation 中阅读更多内容。

2) 否则只需扩展 DetailView attributes 部分中属性 area 的定义:

[
    'attribute' => 'area',
    'value' => $model->area === null ? 'N\A' : $model->area,
],

您可以通过在模型中定义规则来验证 Float 类型验证...

 ....other rules....
 [['area'],'integer', 'integerOnly' => false,],
 ...other rule...