SilverStripe - 在为另一个管理模型提供新条目时更新一个管理模型
SilverStripe - Update one admin model when another is given new entries
在 SilverStripe 中,我有两个管理模型:服务和位置。位置是位置列表。服务是这些位置可以提供的服务列表。但是,只有某些位置可以提供某些服务。我想要做的是,每当添加一个新位置(或者如果一个位置被删除或重命名),我想将它添加到每个服务下的复选框字段中(这样,内容管理员可以轻松控制在何处提供哪些服务随时)。
这是服务数据对象代码(注意:我还没有在复选框字段中添加):
class Services extends DataObject {
private static $db = array(
'Name' => 'varchar',
);
public static $summary_fields = array(
'Name' => 'Title',
);
}
这是 Locations 数据对象代码:
class Locations extends DataObject {
private static $db = array(
'Name' => 'varchar',
'AcceptingAppointments' => 'boolean',
);
public static $summary_fields = array(
'Name' => 'Title',
'AcceptingAppointments' => 'Accepting Appointments?',
);
public function AcceptingAppointments() {
return ($this->AcceptingAppointments==true ? 'Yes':'No');
}
}
目前一切正常。我可以添加、编辑和删除位置和服务。但是,我不知道如何对服务进行编码,以便每当内容管理员添加、删除或重命名位置条目时,每个服务都会更新所有位置的完整列表。
在这方面使用 $has_many
关系有用吗?
需要的是 Service
和 Location
之间的 $many_many
关系。我们想要多对多的关系,因为一个服务可以有很多位置,一个位置可以有很多服务。要了解有关使用 $many_many
关系的更多信息,请阅读 this lesson or this documentation。
一旦我们定义了一个 $many_many
关系,我们就可以添加一个 CheckboxSetField
来控制这个关系。
请注意,我已将 Locations
class 重命名为 Location
,将 Services
重命名为 Service
,因为我认为 class 名称应该是单数。
服务
class Service extends DataObject {
private static $db = array(
'Name' => 'Varchar'
);
private static $belongs_many_many = array(
'Locations' => 'Location'
);
private static $summary_fields = array(
'Name' => 'Title'
);
private static $field_labels = array(
'Name'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
if ($this->ID) {
$fields->addFieldToTab('Root.Locations', CheckboxSetField::create(
'Locations',
'Locations',
Location::get()->map()
));
}
return $fields;
}
}
在 Location
上,我们将 $belongs_many_many
关系添加回 Service
,以便我们可以控制双方的关系。
位置
class Location extends DataObject {
private static $db = array(
'Name' => 'Varchar',
'AcceptingAppointments' => 'Boolean'
);
private static $many_many = array(
'Services' => 'Service'
);
private static $summary_fields = array(
'Name',
'AcceptingAppointmentsNice'
);
private static $field_labels = array(
'Name' => 'Title',
'AcceptingAppointmentsNice' => 'Accepting Appointments?'
);
public function AcceptingAppointmentsNice() {
return $this->AcceptingAppointments ? 'Yes' : 'No';
}
public function getCMSFields() {
$fields = parent::getCMSFields();
if ($this->ID) {
$fields->addFieldToTab('Root.Services', CheckboxSetField::create(
'Services',
'Services',
Service::get()->map()
));
}
return $fields;
}
}
CheckboxSetField
的替代方法是 ListboxField
。 ListboxField
是一个整洁的下拉多选字段。如果选项列表很长,这很有用。
class Service extends DataObject {
// ...
public function getCMSFields() {
$fields = parent::getCMSFields();
if ($this->ID) {
$fields->addFieldToTab('Root.Locations', ListboxField::create(
'Locations',
'Locations',
Location::get()->map('ID', 'Name')->toArray(),
array(),
null,
true
));
}
return $fields;
}
}
另请注意,$summary_fields
必须声明为 private
变量,而不是 public
变量。
在 SilverStripe 中,我有两个管理模型:服务和位置。位置是位置列表。服务是这些位置可以提供的服务列表。但是,只有某些位置可以提供某些服务。我想要做的是,每当添加一个新位置(或者如果一个位置被删除或重命名),我想将它添加到每个服务下的复选框字段中(这样,内容管理员可以轻松控制在何处提供哪些服务随时)。
这是服务数据对象代码(注意:我还没有在复选框字段中添加):
class Services extends DataObject {
private static $db = array(
'Name' => 'varchar',
);
public static $summary_fields = array(
'Name' => 'Title',
);
}
这是 Locations 数据对象代码:
class Locations extends DataObject {
private static $db = array(
'Name' => 'varchar',
'AcceptingAppointments' => 'boolean',
);
public static $summary_fields = array(
'Name' => 'Title',
'AcceptingAppointments' => 'Accepting Appointments?',
);
public function AcceptingAppointments() {
return ($this->AcceptingAppointments==true ? 'Yes':'No');
}
}
目前一切正常。我可以添加、编辑和删除位置和服务。但是,我不知道如何对服务进行编码,以便每当内容管理员添加、删除或重命名位置条目时,每个服务都会更新所有位置的完整列表。
在这方面使用 $has_many
关系有用吗?
需要的是 Service
和 Location
之间的 $many_many
关系。我们想要多对多的关系,因为一个服务可以有很多位置,一个位置可以有很多服务。要了解有关使用 $many_many
关系的更多信息,请阅读 this lesson or this documentation。
一旦我们定义了一个 $many_many
关系,我们就可以添加一个 CheckboxSetField
来控制这个关系。
请注意,我已将 Locations
class 重命名为 Location
,将 Services
重命名为 Service
,因为我认为 class 名称应该是单数。
服务
class Service extends DataObject {
private static $db = array(
'Name' => 'Varchar'
);
private static $belongs_many_many = array(
'Locations' => 'Location'
);
private static $summary_fields = array(
'Name' => 'Title'
);
private static $field_labels = array(
'Name'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
if ($this->ID) {
$fields->addFieldToTab('Root.Locations', CheckboxSetField::create(
'Locations',
'Locations',
Location::get()->map()
));
}
return $fields;
}
}
在 Location
上,我们将 $belongs_many_many
关系添加回 Service
,以便我们可以控制双方的关系。
位置
class Location extends DataObject {
private static $db = array(
'Name' => 'Varchar',
'AcceptingAppointments' => 'Boolean'
);
private static $many_many = array(
'Services' => 'Service'
);
private static $summary_fields = array(
'Name',
'AcceptingAppointmentsNice'
);
private static $field_labels = array(
'Name' => 'Title',
'AcceptingAppointmentsNice' => 'Accepting Appointments?'
);
public function AcceptingAppointmentsNice() {
return $this->AcceptingAppointments ? 'Yes' : 'No';
}
public function getCMSFields() {
$fields = parent::getCMSFields();
if ($this->ID) {
$fields->addFieldToTab('Root.Services', CheckboxSetField::create(
'Services',
'Services',
Service::get()->map()
));
}
return $fields;
}
}
CheckboxSetField
的替代方法是 ListboxField
。 ListboxField
是一个整洁的下拉多选字段。如果选项列表很长,这很有用。
class Service extends DataObject {
// ...
public function getCMSFields() {
$fields = parent::getCMSFields();
if ($this->ID) {
$fields->addFieldToTab('Root.Locations', ListboxField::create(
'Locations',
'Locations',
Location::get()->map('ID', 'Name')->toArray(),
array(),
null,
true
));
}
return $fields;
}
}
另请注意,$summary_fields
必须声明为 private
变量,而不是 public
变量。