Я могу придумать два возможных способа сделать это, первый (который определенно работает) будет использовать класс-обертку в вашем контроллере следующим образом:
public class CArea
{
public list<Contact> liContacts {get; set;}
public string strAreaName {get; set;}
public CArea(Contact sContact)
{
strAreaName = sContact.City;
liContacts = new list<Contact>{sContact};
}
}
public list<CArea> liAreas {get; set;}
private map<string, CArea> mapAreas = new map<string, CArea>();
// **snip**
// fill up the list: (assuming contacts)
for(Contact sContact : myContactList}
{
if(mapAreas.get(sContact.City) == null)
{
mapAreas.put(sContact.City, new CArea(sContact));
liAreas.add(mapAreas.get(sContact.City);
}
else
{
mapAreas.get(sContact.City).liContacts.add(sContact);
}
}
Теперь liAreas
имеет список CArea
объектов, каждый из которых содержит список контактов, поэтому вы можете перебрать этот список на своей странице:
<apex:repeat var="a" value="{!liAreas}">
<apex:outputText value="{!a.strName}"/>
<apex:repeat var="c" value="{!a.liContacts}">
<apex:outputText value="{!c.FirstName c.LastName}"/>
</apex:repeat>
</apex:repeat>
Вариант № 2:
Это потенциально намного проще, но я не пробовал динамические привязки с двумя уровнями, подобными этим. Настройка, аналогичная предыдущей, но используйте карту областей для списка контактов:
public map<string, list<Contact>> mapAreaToContacts {get; set;}
Заполнение должно быть достаточно простым, очень похожим на приведенный выше код. Теперь используйте динамические привязки Visualforce, как описано в Руководство разработчика Visualforce , в разделе Поддержка карт и списков .
Удачи!