php – 动态创建Yii FormModel对象(CFormModel)
我正在开发一个涉及在高级抽象中生成表单的应用程序(它是一个CMS应用程序).我想动态创建CFormModel对象并动态设置表单字段.我想我可以通过扩展CFormModel,然后动态创建表示表单字段的类属性(Yii术语中的“属性”)来做到这一点.
为了说明,而不是在以下类中指定登录表单(在文件中定义): // From: http://www.yiiframework.com/doc/guide/1.1/en/form.model class LoginForm extends CFormModel { public $username; public $password; public $rememberMe=false; private $_identity; public function rules() { return array( array('username,password','required'),array('rememberMe','boolean'),array('password','authenticate'),// assume function authenticate defined elsewhere ); } } 我想这样做: class MyFormModel extends CFormModel { protected $_rules = array(); public function __construct($attributes=array(),$rules=array()) { foreach ($attributes as $i => $attr) { $this->{$attr} = ???; // <<== This is the key here } // pass in array of rules as described in Yii doc for CFormModel $this->_rules = $rules; } public function rules() { return $_rules; } } 并在需要时调用它,如下所示: $myModelObj = new MyFormModel($attr,$rules); 其中: $attr = array( 'username','rememberMe','password',); $rules = array( array('username,// assume function authenticate defined elsewhere ); 请注意,在我要完成的任务中,没有任何文件中写入“LoginClass”,它是在代码中即时创建的. 这将是我创建表单(在视图中)做这样的事情: // based on http://www.yiiframework.com/doc/guide/1.1/en/form.view <?php echo $wForm->textField($myModelObj,'username'); ?> 等等 我试过这个,$this-> {$attr}行失败了: Property "MyFormModel.username" is not defined. 实际上该行的代码只是: $this->{$attr}; ???表示我不确定要分配给它的内容.在Yii doc示例中,它们只是将字段定义为公共类变量. 我应该使用魔术方法吗? 我想在这里做什么甚至可能吗? 解决方法
您可能知道Yii使用
OOP overloading来解析您的AR属性.
你需要做的是类似于Yii内部所做的. 定义一个硬编码属性来存储所有自定义属性,如数组:$_data 并且此数据将是一个数组,并将保存您在运行时添加的所有属性.您可能需要通过覆盖魔术方法(setter,getters,isset)来挑战验证,如Yii所做,首先解析来自$_data属性持有者的属性名称. 您将在CActiveRecord中找到的某种代码可以查找所有类似__XXX的方法. 如果您将AR属性处理复制到您的自定义类,您将在您的级别上运行所有这些,并且当您的魔法方法无法解析时,它将回退到Yii. 此外,我会研究行为,因为您可以将许多常用函数委托给行为类. 使用组件行为 组件支持mixin模式,可以附加一个或多个行为.行为是一种对象,其方法可以通过收集功能而不是专门化(即正常的类继承)由其附加组件“继承”.组件可以附加多个行为,从而实现“多重继承”. 行为类必须实现IBehavior接口.大多数行为都可以从CBehavior基类扩展.如果需要将行为附加到模型,它也可以从CModelBehavior或CActiveRecordBehavior延伸,这实现了模型的特定附加功能. 要使用行为,必须首先通过调用行为的attach()方法将其附加到组件.然后我们可以通过组件调用行为方法: // $name uniquely identifies the behavior in the component $component->attachBehavior($name,$behavior); // test() is a method of $behavior $component->test(); 可以像组件的普通属性一样访问附加行为.例如,如果名为tree的行为附加到组件,我们可以使用以下命令获取对此行为对象的引用: $behavior=$component->tree; // equivalent to the following: // $behavior=$component->asa('tree'); 可以暂时禁用某个行为,以便通过该组件无法使用其方法.例如, $component->disableBehavior($name); // the following statement will throw an exception $component->test(); $component->enableBehavior($name); // it works now $component->test(); 附加到同一组件的两个行为可能具有相同名称的方法.在这种情况下,第一个附加行为的方法将优先. 与events一起使用时,行为更加强大.当附加到组件时,行为可以将其某些方法附加到组件的某些事件.通过这样做,行为有机会观察或改变组件的正常执行流程. 还可以通过附加到的组件访问行为的属性.这些属性包括公共成员变量和通过行为的getter和/或setter定义的属性.例如,如果某个行为具有名为xyz的属性,并且该行为附加到组件$a.然后我们可以使用表达式$a-> xyz来访问行为的属性. 更多阅读: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |