SilverStripe - 过滤 DataList 结果以删除重复项并按值分组
SilverStripe - Filter DataList results to remove duplicates and group by value
我正在尝试使用 SilverStripe 中的 DataLists 做一些不同的事情。目标是 return 以这种格式按州排序的商店列表。
已创建名为 StoreLocation.php
的管理模型,其中包含商店数据:
class StoreLocation extends DataObject {
private static $db = array(
'Address' => 'Varchar(250)',
'City' => 'varchar(100)',
'State' => 'varchar(2)',
'Zip' => 'varchar(10)'
);
private static $has_one = array(
'Store' => 'Store'
);
private static $summary_fields = array(
'getStoreSummaryLabel' => 'Store Info'
);
private static $field_labels = array(
'Address',
'City',
'State',
'Zip'
);
public function getStoreSummaryLabel() {
$storeName = $this->Store()->Name;
return sprintf("%s (%s)", $storeName, $this->addressPretty());
}
// tidy up the CMS by not showing these fields
public function getCMSFields() {
$fields = parent::getCMSFields();
$siteConfig = SiteConfig::current_site_config();
$statesDropdown = DropdownField::create("State", "State", $siteConfig->stateList())
->setEmptyString('Select State');
if ($siteConfig->GoogleAPIKey == "") {
$fields->addFieldToTab("Root.Main", new HeaderField("error","Error: No Google API Key Defined!",2));
}
$fields->removeFieldsFromTab('Root.Main', [
'State',
]);
return $fields;
}
public function addressPretty() {
return sprintf("%s %s, %s %s", $this->data()->Address, $this->data()->City, $this->data()->State, $this->data()->Zip);
}
}
被StoreLocation
引用的Store
DataObject
:
class Store extends DataObject {
private static $db = array(
'Name' => 'Varchar(100)'
);
private static $has_one = array(
'Logo' => 'Image'
);
private static $has_many = array(
'Locations' => 'StoreLocation'
);
private static $summary_fields = array(
'Name' => 'Name'
);
private static $field_labels = array(
'Name',
'Logo'
);
// tidy up the CMS by not showing these fields
public function getCMSFields() {
$fields = parent::getCMSFields();
return $fields;
}
static $default_sort = "Name ASC";
}
问题是我需要 return 各州的商店列表,但删除所有重复的商店名称,因为我不显示商店地址。我只需要显示名称(我不知道为什么。这是必须的)。因此,例如,Store ABC in Alabama 可能有 5 个结果,因为它有 5 个位置,但我只想 return Store ABC once for Alabama。
只需 return 以这种格式 StoreLocation
数据列表 returns 是正确的结果,但有大量重复项,并且州名在每个商店上方重复:
更新:我在发现这个 link 后找到了一个可能的解决方案,其中包含自定义嵌套分组列表 class 文件:https://www.silverstripe.org/community/forums/general-questions/show/24195
通过使用 class,我能够制作一个 GroupedList,我可以在其中按数据对象的 2 个不同方面进行排序:
public function GroupedEntries() {
return NestedGroupedList::create(
StoreLocation::get()->sort('State ASC, StoreID ASC')
);
}
然后,在模板中,我这样设置:
<div class="col-md-12" style="padding-bottom:40px;">
<div class="retailer-listing" style="text-align: left;">
<% loop $GroupedEntries.GroupedBy('State,StoreID') %>
<strong>$State</strong><br />
<% loop $Children %>
<% loop $Children.First %>
$Store.Name<br />
<% end_loop %>
<% end_loop %>
<% end_loop %>
</div>
</div>
这似乎是 return 正确组织结果,按州字母顺序对每个商店名称的第一个实例进行排序。经过一些猜测和检查测试,直到我得到正确的循环。
首先我们创建一个函数来 return GroupedList
页面控制器中的 StoreLocation
个项目:
public function getGroupedStoreLocations() {
return GroupedList::create(StoreLocation::get()->sort('State'));
}
然后,在我们的页面模板中,我们在 GroupedStoreLocations
函数上调用 GroupedBy(State)
来对列表进行分组。这 return 是一个 ArrayList
组项,其中包含索引(阶段名称)和属于该组的子项列表。在我们的 GroupedStoreLocations
循环中,我们可以遍历 $Children
来遍历 GroupedList
:
中的每个项目
<% loop $GroupedStoreLocations.GroupedBy(State) %>
<h4>$State</h4>
<ul>
<% loop $Children %>
<li>$Store.Name</li>
<% end_loop %>
</ul>
<% end_loop %>
在 GroupedList
Documentation 页面查看更多信息。
我在发现这个 link 后找到了解决方案,其中包含自定义嵌套分组列表 class 文件:https://www.silverstripe.org/community/forums/general-questions/show/24195
通过使用 class,我能够制作一个 GroupedList,我可以在其中按数据对象的 2 个不同方面进行排序:
public function GroupedEntries() {
return NestedGroupedList::create(
StoreLocation::get()->sort('State ASC, StoreID ASC')
);
}
然后,在模板中,我这样设置:
<div class="col-md-12" style="padding-bottom:40px;">
<div class="retailer-listing" style="text-align: left;">
<% loop $GroupedEntries.GroupedBy('State,StoreID') %>
<strong>$State</strong><br />
<% loop $Children %>
<% loop $Children.First %>
$Store.Name<br />
<% end_loop %>
<% end_loop %>
<% end_loop %>
</div>
</div>
这似乎返回了正确的结果组织,按州字母顺序对每个商店名称的第一个实例进行排序。经过一些猜测和检查测试,直到我得到正确的循环。
我正在尝试使用 SilverStripe 中的 DataLists 做一些不同的事情。目标是 return 以这种格式按州排序的商店列表。
已创建名为 StoreLocation.php
的管理模型,其中包含商店数据:
class StoreLocation extends DataObject {
private static $db = array(
'Address' => 'Varchar(250)',
'City' => 'varchar(100)',
'State' => 'varchar(2)',
'Zip' => 'varchar(10)'
);
private static $has_one = array(
'Store' => 'Store'
);
private static $summary_fields = array(
'getStoreSummaryLabel' => 'Store Info'
);
private static $field_labels = array(
'Address',
'City',
'State',
'Zip'
);
public function getStoreSummaryLabel() {
$storeName = $this->Store()->Name;
return sprintf("%s (%s)", $storeName, $this->addressPretty());
}
// tidy up the CMS by not showing these fields
public function getCMSFields() {
$fields = parent::getCMSFields();
$siteConfig = SiteConfig::current_site_config();
$statesDropdown = DropdownField::create("State", "State", $siteConfig->stateList())
->setEmptyString('Select State');
if ($siteConfig->GoogleAPIKey == "") {
$fields->addFieldToTab("Root.Main", new HeaderField("error","Error: No Google API Key Defined!",2));
}
$fields->removeFieldsFromTab('Root.Main', [
'State',
]);
return $fields;
}
public function addressPretty() {
return sprintf("%s %s, %s %s", $this->data()->Address, $this->data()->City, $this->data()->State, $this->data()->Zip);
}
}
被StoreLocation
引用的Store
DataObject
:
class Store extends DataObject {
private static $db = array(
'Name' => 'Varchar(100)'
);
private static $has_one = array(
'Logo' => 'Image'
);
private static $has_many = array(
'Locations' => 'StoreLocation'
);
private static $summary_fields = array(
'Name' => 'Name'
);
private static $field_labels = array(
'Name',
'Logo'
);
// tidy up the CMS by not showing these fields
public function getCMSFields() {
$fields = parent::getCMSFields();
return $fields;
}
static $default_sort = "Name ASC";
}
问题是我需要 return 各州的商店列表,但删除所有重复的商店名称,因为我不显示商店地址。我只需要显示名称(我不知道为什么。这是必须的)。因此,例如,Store ABC in Alabama 可能有 5 个结果,因为它有 5 个位置,但我只想 return Store ABC once for Alabama。
只需 return 以这种格式 StoreLocation
数据列表 returns 是正确的结果,但有大量重复项,并且州名在每个商店上方重复:
更新:我在发现这个 link 后找到了一个可能的解决方案,其中包含自定义嵌套分组列表 class 文件:https://www.silverstripe.org/community/forums/general-questions/show/24195
通过使用 class,我能够制作一个 GroupedList,我可以在其中按数据对象的 2 个不同方面进行排序:
public function GroupedEntries() {
return NestedGroupedList::create(
StoreLocation::get()->sort('State ASC, StoreID ASC')
);
}
然后,在模板中,我这样设置:
<div class="col-md-12" style="padding-bottom:40px;">
<div class="retailer-listing" style="text-align: left;">
<% loop $GroupedEntries.GroupedBy('State,StoreID') %>
<strong>$State</strong><br />
<% loop $Children %>
<% loop $Children.First %>
$Store.Name<br />
<% end_loop %>
<% end_loop %>
<% end_loop %>
</div>
</div>
这似乎是 return 正确组织结果,按州字母顺序对每个商店名称的第一个实例进行排序。经过一些猜测和检查测试,直到我得到正确的循环。
首先我们创建一个函数来 return GroupedList
页面控制器中的 StoreLocation
个项目:
public function getGroupedStoreLocations() {
return GroupedList::create(StoreLocation::get()->sort('State'));
}
然后,在我们的页面模板中,我们在 GroupedStoreLocations
函数上调用 GroupedBy(State)
来对列表进行分组。这 return 是一个 ArrayList
组项,其中包含索引(阶段名称)和属于该组的子项列表。在我们的 GroupedStoreLocations
循环中,我们可以遍历 $Children
来遍历 GroupedList
:
<% loop $GroupedStoreLocations.GroupedBy(State) %>
<h4>$State</h4>
<ul>
<% loop $Children %>
<li>$Store.Name</li>
<% end_loop %>
</ul>
<% end_loop %>
在 GroupedList
Documentation 页面查看更多信息。
我在发现这个 link 后找到了解决方案,其中包含自定义嵌套分组列表 class 文件:https://www.silverstripe.org/community/forums/general-questions/show/24195
通过使用 class,我能够制作一个 GroupedList,我可以在其中按数据对象的 2 个不同方面进行排序:
public function GroupedEntries() {
return NestedGroupedList::create(
StoreLocation::get()->sort('State ASC, StoreID ASC')
);
}
然后,在模板中,我这样设置:
<div class="col-md-12" style="padding-bottom:40px;">
<div class="retailer-listing" style="text-align: left;">
<% loop $GroupedEntries.GroupedBy('State,StoreID') %>
<strong>$State</strong><br />
<% loop $Children %>
<% loop $Children.First %>
$Store.Name<br />
<% end_loop %>
<% end_loop %>
<% end_loop %>
</div>
</div>
这似乎返回了正确的结果组织,按州字母顺序对每个商店名称的第一个实例进行排序。经过一些猜测和检查测试,直到我得到正确的循环。