Yii2 ActiveForm小部件渲染过程

问题:

(1)ActiveForm::begin()做了什么,ActiveForm::end()做了什么,中间echo的ActiveForm::field()内容是如何渲染的;

(2)我们在ActiveRecord模型类的rules规则里定义的验证方法如何在客户端页面同样生效的;

首先看Yii2 ActiveForm小部件渲染过程

1. yii\widght\ActiveForm::begin($config);

这里实例化了ActiveForm对象,通过 __construct() 调用 init(),在这里生成小部件的唯一id:getId(),打开输出缓冲:ob_start();ob_implicit_flush(false);

2. 小部件实例化后就可以通过它的field()方法生成表单内容控件

echo $form->field($model,$attribute,$options);//生成默认的textInput控件

echo $form->field($model,$attribute,$options)->radio();//生成radio控件

这里有一个关键的地方:ActiveField对象在ActiveForm::field()方法中被创建,而其内容的渲染源自于`echo`的调用会触发ActiveField的__toString()魔术方法,这里调用了ActitveField的render()方法通过ActiveField的begin()与end()方法渲染完整内容。
(1) ActiveField::begin()会通过ActiveField::getClientOptions()方法获得指定属性的详细信息,包括验证规则,并填充到对应$form的$attributes属性中。
(2) 这里关键在于ActiveField::getClientOptions()做了什么:
    1)通过当前$model判断该$attribute是否有效;
    2)如果开启了客户端验证,则通过$model->getActiveValidators($attribute)获得与当前$attribute当前scenario相关的验证规则;
    3)遍历上一步获得的验证规则,通过每个验证器(yii\vaidators\Validator的子类的实例)的clientValidateAttribute()方法获得对应验证规则的客户端验证的js内容;
    4)填充$attribute的id,name等信息后,将上一步获得的所有客户端验证js内容组合到一个完整的js匿名函数中;
    5)返回上述所有步骤获得的信息,交由begin()存入对应$form的$attributes中。

(3) 当所有ActiveField都执行完毕,就来到了ActiveForm::end(),

    1)通过ob_get_content()拿到上述所有field的输出;

    2)如果开启了客户端验证,则会注入ActiveFormAsset资源包内容,并注入yii.activeForm.js的yiiActiveForm($attributes, $options);js内容。

(4) 页面加载时会执行上面注入的yiiActiveForm.init()方法。

由于传入的$attributes参数包含了所有$attribute的详细描述与客户端验证需执行的js验证方法,在yii.activeForm.js中就可以实现对各个属性的事件监听并触发对应的验证逻辑。

猜你喜欢

转载自www.cnblogs.com/ling-diary/p/9220111.html
今日推荐