Php 如何动态更改字段';s型银条

Php 如何动态更改字段';s型银条,php,forms,object,field,silverstripe,Php,Forms,Object,Field,Silverstripe,我试图根据SilverStripe中的一些条件动态更改字段的类型 我有一个字段,例如CheckboxField(),我需要将其复制并更改为其他类型,例如DropdownField()或任何其他类型的字段 在将对象推送到表单之前,有没有办法做到这一点?这里的最佳做法是什么?您可以使用replaceField 您可以在getCMSField中添加一个条件 function getCMSFields() { $fields = parent::getCMSFields(); $sour

我试图根据SilverStripe中的一些条件动态更改字段的类型

我有一个字段,例如
CheckboxField()
,我需要将其复制并更改为其他类型,例如
DropdownField()
或任何其他类型的字段


在将对象推送到表单之前,有没有办法做到这一点?这里的最佳做法是什么?

您可以使用replaceField


您可以在getCMSField中添加一个条件

function getCMSFields() {
    $fields = parent::getCMSFields();
    $source = SomeDataObject::get();
    $fields->removeByName('MyField');
    if($source->count() > 1) {
        $fields->addFieldToTab('MyTab', DropdownField::create('MyField', 'My field', $source->map()->toArray()));
    } else {
        $fields->addFieldToTab('MyTab', CheckboxField::create('MyField', 'My field', $source->first()->Name));
    }
    return $fields;
}

希望有帮助。

这是用于后端SilverStripe CMS(又名。
getCMSFields
)还是其他什么?它应该非常简单,只需
删除
复选框字段的
按名称
,然后
添加字段到选项卡
(或
推送
)您想要的任何新字段。如果是
getCMSFields
,您能否向我们展示您当前拥有的数据,以便我们能够根据您的问题创建一个适合您的答案?另外,当您回到我前面的问题时,您打算如何存储不同的数据?我假设您的目的是将数据存储为不同的DB,或者
有一个
属性?只需向我们提供更多信息:)@Turnerj这是一个前端用户表单…表单。我正在创建一个自定义字段,可以将其更改为任何其他类型的字段,但我不确定如何正确执行此部分。我目前只使用一个条件语句来切换-ahhh,
CheckboxSetField
,而不是
CheckboxField
!我想你真的已经有了解决问题的方法,关于如何做,你真正的问题是什么是最好的方法?您链接到的代码是一种更优化的方法,我可能会以类似的方式实现它。如果这是您的代码,那么这是一种很好的方法。其中的一个问题是,
CheckboxField
基本上存储的数据与
DropdownField
不同。他可能需要使用不同的DB属性。因此,虽然他仍然可以利用
replaceField
功能,但他可能需要为
DropdownField
使用不同的名称。您最好使用显示逻辑,您可以根据某些条件隐藏和显示字段,例如,如果选中复选框,然后,您可以显示下拉字段。虽然这是一个潜在的解决方案,但如果这是针对
ModelAdmin
中的
DataObject
,则该字段实际上已经存在,因为存在脚手架,所以您的示例将再次添加该字段。正如我在另一个答案中提到的,它有一个基本的存储缺陷,
DropdownField
存储的数据与
CheckboxField
存储的数据不同。您的CheckboxField将值转换为
0
1
,因此即使从源代码列表中传递第一个名称,也不会按预期存储在
MyField
属性中。我目前正在这样做(请参阅上面的链接)但不确定这是否是最佳做法?@Turnerj您可以在条件之前使用
removeByName
删除字段
DropdownField
不存储任何数据,它不是
DBField
,而是
FormField
MyField
可以子类化
TextField
,并用于保存从下拉列表或复选框中选择的值。您甚至可以在写入db之前使用函数
onbeforewite
来操作该值。@cbarberis,我知道您可以删除该字段,我只是提到了它,因为您最初的帖子没有考虑到这一点。要使
getCMSFields
自动保存,
MyField
需要是DB属性,或者
有一个
关系才能使用
Form::saveInto
。虽然您可以将一个
DBField
子类化以处理这两种字段类型的值,但会出现一些问题,如在保存复选框时,将提供的值为1,可能与DB对象的ID值相同,并且您不知道使用了哪种字段类型。@cbarberis(cont.),尽管您可以避开这个问题,这不是如何处理它的开箱即用,所以任何人看这个答案可能会得到错误的印象。我们的几条来来回回的评论是唯一能向任何访问者描述潜在问题的东西。我想把它记在你的答案里吧。
function getCMSFields() {
    $fields = parent::getCMSFields();
    $source = SomeDataObject::get();
    $fields->removeByName('MyField');
    if($source->count() > 1) {
        $fields->addFieldToTab('MyTab', DropdownField::create('MyField', 'My field', $source->map()->toArray()));
    } else {
        $fields->addFieldToTab('MyTab', CheckboxField::create('MyField', 'My field', $source->first()->Name));
    }
    return $fields;
}