循环遍历具有 $has_many 关系的数据对象?
Looping through a dataobject with a $has_many relationship?
我的 DashboardPage
与 PastEvent
数据对象之间存在 $has_many
关系。在我的 DashboardPage.ss 模板中,我希望能够遍历所有 PastEvents
。我相信由于 $has_many 关系,我应该能够在 DashboardPage.ss
模板上执行以下操作:
DashboardPage.ss
<% loop $PastEvents %>
<div>
<div>$EventName</div>
<div>$ClassType</div>
etc...
</div>
<% end_loop %>
但是没有任何显示。我错过了什么?
DashboardPage.php
<?php
class DashboardPage extends Page implements TemplateGlobalProvider {
private static $db = array(
'Testing' => 'Varchar(255)'
);
private static $has_many = array(
'PastEvents' => 'PastEvent'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeByName('Content');
return $fields;
}
public static function get_template_global_variables() {
return array('DashboardLink' => 'getDashboardLink');
}
public static function getDashboardLink($action='') {
$page = DashboardPage::get()->first();
return $page ? $page->Link($action) : '';
}
}
class DashboardPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'show'
);
public function init() {
parent::init();
Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.carousel.css');
Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.theme.css');
Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.transitions.css');
}
public function show(){
dd('Coming here');
}
}
PastEvent.php
<?php
class PastEvent extends DataObject {
private static $db = array(
'EventName' => 'Varchar(255)',
'ClassType' => 'Varchar(255)',
'Instructor' => 'Varchar(255)',
'EmbedCode' => 'Text',
'EventDate' => 'Date',
'Time' => 'Time'
);
private static $has_one = array(
'BranchLocation' => 'BranchLocation',
'DashboardPage' => 'DashboardPage'
);
private static $summary_fields = array(
'EventName' => 'EventName',
'BranchLocation.Name' => 'Branch Location',
'ClassType' => 'ClassType',
'Instructor' => 'Instructor',
'EventDate' => 'Event Date',
'Time' => 'Time',
);
public function getCMSFields() {
$fields = new FieldList(
TextField::create('EventName'),
TextField::create('ClassType'),
TextField::create('Instructor'),
DropdownField::create(
'BranchLocationID',
'Branch Location',
BranchLocation::get()->map('ID', 'Name')->toArray()
),
TextareaField::create('EmbedCode'),
DateField::create('EventDate')->setConfig('showcalendar', true)->setDescription('Click inside textbox to open calender'),
TimePickerField::create('Time')
);
return $fields;
}
public function Link() {
return $this->DashboardPage()->Link('show/'.$this->ID);
}
}
您需要在 DashboardPage 上管理 PastEvent
public function getCMSFields() {
...
$fields->push(GridField::create('PastEvents', 'Past Events',
$this->PastEvents(),
singleton('PastEvent')->canEdit()
? GridFieldConfig_RecordEditor::create()
: GridFieldConfig_RecordViewer::create()
));
...
}
您可以从其他地方添加过去的事件,前提是您使用“/dashboard”创建了您的页面url。
$dashboard = SiteTree::get_by_link('dashboard');
$events = $dashboard->PastEvents();
$events->add($this->createNewEvent());
您不需要 show()
操作来显示 DashboardPage(默认使用隐式 index()
操作)。页面操作扩展页面 url,因此当您请求 /dashboard/show
时将调用您的操作,这似乎是您的意图。
改进您的模板以显示没有事件:
<% if $PastEvents.Count %>
<ul>
<% loop $PastEvents %>
<li>
<a href="$Link">$EventName</a>
<div>$ClassType</div>
...
</li>
<% end_loop %>
</ul>
<% else %>
<p>There are no past events.</p>
<% end_if %>
由于您的页面提供了适当的 link 到 show
操作
public function Link() {
return $this->DashboardPage()->Link('show/'.$this->ID);
}
你的表演动作可能是这样的
public function show($eventID = 0) {
$event = $this->PastEvents()->byID($eventID);
if (!$event) {
$this->httpError(404);
}
// render with templates/Page.ss and templates/Layout/PastEventDetails.ss
return $event->renderWith(array('PastEventDetails', 'Page'));
}
我的 DashboardPage
与 PastEvent
数据对象之间存在 $has_many
关系。在我的 DashboardPage.ss 模板中,我希望能够遍历所有 PastEvents
。我相信由于 $has_many 关系,我应该能够在 DashboardPage.ss
模板上执行以下操作:
DashboardPage.ss
<% loop $PastEvents %>
<div>
<div>$EventName</div>
<div>$ClassType</div>
etc...
</div>
<% end_loop %>
但是没有任何显示。我错过了什么?
DashboardPage.php
<?php
class DashboardPage extends Page implements TemplateGlobalProvider {
private static $db = array(
'Testing' => 'Varchar(255)'
);
private static $has_many = array(
'PastEvents' => 'PastEvent'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeByName('Content');
return $fields;
}
public static function get_template_global_variables() {
return array('DashboardLink' => 'getDashboardLink');
}
public static function getDashboardLink($action='') {
$page = DashboardPage::get()->first();
return $page ? $page->Link($action) : '';
}
}
class DashboardPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'show'
);
public function init() {
parent::init();
Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.carousel.css');
Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.theme.css');
Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.transitions.css');
}
public function show(){
dd('Coming here');
}
}
PastEvent.php
<?php
class PastEvent extends DataObject {
private static $db = array(
'EventName' => 'Varchar(255)',
'ClassType' => 'Varchar(255)',
'Instructor' => 'Varchar(255)',
'EmbedCode' => 'Text',
'EventDate' => 'Date',
'Time' => 'Time'
);
private static $has_one = array(
'BranchLocation' => 'BranchLocation',
'DashboardPage' => 'DashboardPage'
);
private static $summary_fields = array(
'EventName' => 'EventName',
'BranchLocation.Name' => 'Branch Location',
'ClassType' => 'ClassType',
'Instructor' => 'Instructor',
'EventDate' => 'Event Date',
'Time' => 'Time',
);
public function getCMSFields() {
$fields = new FieldList(
TextField::create('EventName'),
TextField::create('ClassType'),
TextField::create('Instructor'),
DropdownField::create(
'BranchLocationID',
'Branch Location',
BranchLocation::get()->map('ID', 'Name')->toArray()
),
TextareaField::create('EmbedCode'),
DateField::create('EventDate')->setConfig('showcalendar', true)->setDescription('Click inside textbox to open calender'),
TimePickerField::create('Time')
);
return $fields;
}
public function Link() {
return $this->DashboardPage()->Link('show/'.$this->ID);
}
}
您需要在 DashboardPage 上管理 PastEvent
public function getCMSFields() {
...
$fields->push(GridField::create('PastEvents', 'Past Events',
$this->PastEvents(),
singleton('PastEvent')->canEdit()
? GridFieldConfig_RecordEditor::create()
: GridFieldConfig_RecordViewer::create()
));
...
}
您可以从其他地方添加过去的事件,前提是您使用“/dashboard”创建了您的页面url。
$dashboard = SiteTree::get_by_link('dashboard');
$events = $dashboard->PastEvents();
$events->add($this->createNewEvent());
您不需要 show()
操作来显示 DashboardPage(默认使用隐式 index()
操作)。页面操作扩展页面 url,因此当您请求 /dashboard/show
时将调用您的操作,这似乎是您的意图。
改进您的模板以显示没有事件:
<% if $PastEvents.Count %>
<ul>
<% loop $PastEvents %>
<li>
<a href="$Link">$EventName</a>
<div>$ClassType</div>
...
</li>
<% end_loop %>
</ul>
<% else %>
<p>There are no past events.</p>
<% end_if %>
由于您的页面提供了适当的 link 到 show
操作
public function Link() {
return $this->DashboardPage()->Link('show/'.$this->ID);
}
你的表演动作可能是这样的
public function show($eventID = 0) {
$event = $this->PastEvents()->byID($eventID);
if (!$event) {
$this->httpError(404);
}
// render with templates/Page.ss and templates/Layout/PastEventDetails.ss
return $event->renderWith(array('PastEventDetails', 'Page'));
}