yii2.动态地向模型添加属性和规则 [英] Yii2. Adding attribute and rule dynamically to model

查看:67
本文介绍了yii2.动态地向模型添加属性和规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小部件,我想避免用户向他们的模型添加代码(我知道这会更容易,但使用它来学习新东西).

I am writing a widget and I want to avoid user adding code to their model (I know it would be easier but using it to learn something new).

您是否知道是否可以向模型添加属性(它不在您的数据库中,因此它将是虚拟的)并为该属性添加规则?.您无权更改该型号代码.

Do you know if it is possible to add an attribute (which is not in your database, so it will be virtual) to a model and add a rule for that attribute?. You have no access to change that model code.

我知道 rules 是一个数组.过去,我使用 array_merge 合并了来自父类的规则.可以在外部完成吗?Yii2 有这样的方法吗?

I know rules is an array. In the past I have merged rules from parent class using array_merge. Can it be done externally? Does Yii2 has a method for that?

一个想法是在我的小部件中使用模型"扩展用户提供的模型并在那里使用:

An idea is to extend model provided by the user with a "model" inside my widget an there use:

    public function init() {
      /*Since it is extended this not even would be necessary, 
      I could declare the attribute as usual*/

      $attribute = "categories";
      $this->{$attribute} = null; //To create attribute on the fly

      parent::init();
    }

    public function rules() {
      $rules = [...];

      //Then here merge parent rules with mine.
      return array_merge(parent::rules, $rules);
    }

但是如果我扩展它,当我在 ActiveForm 中使用该模型作为复选框时,它将使用我的CustomModel",所以我想避免这种情况.还有其他想法吗?如何在不扩展他们的模型的情况下做到这一点?

But If I extend it, when I use that model in an ActiveForm in example for a checkbox, it will use my "CustomModel", so I want to avoid that. Any other ideas? How to do it without extending their model?

推荐答案

向现有模型添加动态属性

当您想在运行时向现有模型添加动态属性时.然后你需要一些自定义代码,你需要:一个模型类和一个扩展类,它将做动态部分,并有数组来保存动态信息.这些数组将在需要的函数中与模型类的返回数组合并.

Add Dynamic Attributes to a existing Model

When you want to add dynamic attributes during runtime to a existing model. Then you need some custom code, you need: A Model-Class, and a extended class, which will do the dynamic part and which have array to hold the dynamic information. These array will merged in the needed function with the return arrays of the Model-Class.

这是一种模型,它并不完全有效.但也许你知道你需要做什么:

Here is a kind of mockup, it's not fully working. But maybe you get an idea what you need to do:

class MyDynamicModel extends MyNoneDynamicModel
{

private $dynamicFields = [];
private $dynamicRules = [];

public function setDynamicFields($aryDynamics) {
     $this->dynamicFields = $aryDynamics;
}

public function setDynamicRules($aryDynamics) {
     $this->dynamicRules = $aryDynamics;
}

public function __get($name)
{
    if (isset($this->dynamicFields[$name])) {
        return $this->dynamicFields[$name];
    }

    return parent::__get($name);
}

public function __set($name, $value)
{
if (isset($this->dynamicFields[$name])) {
  return $this->dynamicFields[$name] = $value;
}
return parent::__set($name, $value);
}

public function rules() {
  return array_merge(parent::rules, $this->dynamicRules);
}
}

完整的动态属性

当所有属性都是动态的并且您不需要数据库时.然后使用 Yii2 的新 DynamicModel.该文档还指出:

DynamicModel 是一个模型类,主要用于支持临时数据验证.

DynamicModel is a model class primarily used to support ad hoc data validation.

这是一个完整的表单集成示例来自 Yii2-Wiki,所以我不在这里举个例子.

Here is a full example with form integration from the Yii2-Wiki, so i don't make a example here.

当您想向模型添加属性时,该属性不在数据库中.然后只需在模型中声明一个公共变量:

When you want to add a attribute to the model, which is not in the database. Then just declare a public variable in the model:

public $myVirtualAttribute;

然后您可以像其他(数据库-)属性一样在规则中使用它.

Then you can just use it in the rules like the other (database-)attributes.

要做大规模赋值 不要忘记在模型规则中添加安全规则:

To do Massive Assignment don't forget to add a safe rule to the model rules:

public function rules()
{
    return [
        ...,
        [['myVirtualAttribute'], 'safe'],
        ...
    ];
}

这里很好地解释了原因:Yii2 非数据库(或虚拟)属性在大规模赋值期间未填充?

The reason for this is very well explained here: Yii2 non-DB (or virtual) attribute isn't populated during massive assignment?

这篇关于yii2.动态地向模型添加属性和规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆