简体   繁体   English

Yii2和float字段,默认值为NULL

[英]Yii2 and float field with default value NULL

In the official documentation example "Country" database. 官方文档示例“Country”数据库中。 I decided to add new field (Property) for the country, namely, area . 我决定为国家添加新的字段(Property),即area I added a field named to the MySQL database's table named country with the name area with the following structure: 我在名为country的MySQL数据库表中添加了一个名为country的字段,其名称area具有以下结构:

`area` float DEFAULT NULL

The new field's values in the database takes the default value 0 and in the view it displayed as 0.00 like the following screen shot shows: 数据库中的新字段值采用默认值0 ,在视图中显示为0.00如下面的屏幕截图所示:

在此输入图像描述

In the update form, I added an input field for area like the following: 在更新表单中,我为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>'
        ];
    }

Now all fields in update view, are updated successfully, except the new field area . 现在,更新视图中的所有字段都已成功更新,但新字段area除外。 It, simply, does not updated at all without any error messages. 简单地说,它没有任何错误消息就不会更新。 Why? 为什么?

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 ie Area in KM<sup>2</sup> . 此外,如屏幕截图所示,在视图area标签正确打印出来,但是,在更新视图中,它显示为其HTML实体,即Area in KM<sup>2</sup> Why? 为什么?

In another aspect, I did not like the presentation of area for non defined area country by 0.00, so I decidd to make it to be N/A so I have made the following callback method in models/Country.php: 在另一个方面,我不喜欢0.00的非定义区域国家的区域的呈现,所以我决定使它成为N/A所以我在models / Country.php中做了以下回调方法:

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

However, the above solution generates error in the action view: 但是,上述解决方案在操作视图中生成错误:

'N/A' is not a numeric value. 'N / A'不是数值。

So, I replaced N/A with NULL and the view action works fine and assigned non defined area countries with (not set) in the view instead of 0.00 . 因此,我用NULL替换了N/A ,并且视图操作正常工作,并在视图中为(not set)指定了未定义的区域国家而不是0.00 The last question here, is there any way to make the view printout N\\A for non defined area countries? 这里的最后一个问题是,有没有办法让非定义区域国家的视图打印输出N\\A The action view uses DetailView::widget 操作视图使用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? 为什么?

Because it's not safe attribute. 因为它不是安全的属性。 You said that it's not presented in the rules. 你说它没有出现在规则中。 If you don't want validate it, but want to be able to massively assign it, you should explicitly specify it in the validation rules like so: 如果您不想验证它,但希望能够大量分配它,则应在验证规则中明确指定它,如下所示:

['area', 'safe'],

Read more about model safe attributes in official documentation. 阅读官方文档中有关模型安全属性的更多信息

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 ie Area in KM <sup>2</sup> . 此外,如屏幕截图所示,在视图区域中标签正确打印出来,但是,在更新视图中,它显示为其HTML实体,即KM <sup>2</sup> Why? 为什么?

That's how attribute label renders in DetailView : 这就是属性标签在DetailView呈现的方式:

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

And in Html::activeLabel() which is used by ActiveForm's field() : ActiveForm's field()使用的Html::activeLabel()中:

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

If it's not specified explicitly and automatically taken from attributeLabels() , encoding applies regargless of the options. 如果没有明确指定并自动从attributeLabels() ,则编码适用于无选项。

As as a workaround in ActiveForm I recommend passing it like this: 作为ActiveForm一种解决方法,我建议像这样传递它:

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

I think it's not a big deal to copy such content, because it's not code logic and rarely changed. 我认为复制这些内容并不是什么大问题,因为它不是代码逻辑,很少改变。 And even if it will change, it's very easy to replace it with global search in your editor. 即使它会改变,在编辑器中用全局搜索替换它也很容易。 If you highly against that, maybe it's better to declare it additionally in your model. 如果你高度反对,也许最好在模型中另外声明它。

If you want, you can create issue on Github about that. 如果你愿意,你可以在Github上创建问题。 Maybe I missed something but I didn't find a way to disable encoding for labels in ActiveForm . 也许我错过了一些东西,但我没有找到一种方法来禁用ActiveForm标签编码。

And another workaround is to simply replace html by text representation, something like square km. 另一个解决方法是简单地用文本表示替换html,比如square km. It's a bit longer, but does not have this problems with encoding. 它有点长,但没有编码问题。

The last question here, is there any way to make the view printout N\\A for non defined area countries? 这里的最后一个问题是,有没有办法让非定义区域国家的视图打印输出N \\ A?

I think what you doing in afterFind() is not good because you replace the actual model value with display value. 我认为你在afterFind()做的事情并不好,因为你用显示值替换了实际的模型值。 It can be used somewhere else, for example in update process and lead to some bugs. 它可以在其他地方使用,例如在更新过程中导致一些错误。

You can do it at least with two options in your view. 您可以在视图中至少使用两个选项来执行此操作。

1) If the null values are presented only in area , or you want to display N\\A for other attributes null values too, you can simply replace default null representation like so: 1)如果空值仅在area中显示,或者您想要显示其他属性null值的N\\A ,则可以简单地替换默认的null表示,如下所示:

use Yii;

...

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

You should place this code before rendering DetailView Read more in official documentation . 您应该在呈现DetailView之前放置此代码阅读更多官方文档

2) Otherwise just extend defition of attribute area in DetailView attributes section: 2)否则只需在DetailView attributes部分中扩展属性area定义:

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

You can validate Float type validation by defining rule in model Like... 您可以通过在模型中定义规则来验证浮点类型验证。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM