(получилось много текста - в 2-х словах в следующем сообщении)
Сколько лет не хотел использовать VF component ввиду их глючности и ограниченности, но сегодня пришлось. Хотел сделать красиво. В итоге как и ожидалось в самом финале уперся в проблему.
Задача: наверное банальнее некуда - построить дерево, например ролей.
Обычно такую задачу решаю рендерингом html прямо в контроллере в рекурсивной функции. Но сейчас стоит задача построить дерево с родными input для Salesforce. Чтобы можно было что-то отредактировать для каждой роли и отправить в контроллер на обработку обычным методом.
сделал RoleWrapper для Role__c, который будет содержать List подчиненных ролей (в виде RoleWrappers) для воссоздания иерархической структуры.
public with sharing class RoleWrapper {
public Role__c role { get; set; }
public List<RoleWrapper> childRoles { get; set; }
public RoleWrapper(Role__c role) {
this.role = role;
childRoles = new List<RoleWrapper>();
}
}
дерево в рекурсивной функции строится замечательно.
Теперь задача вывести это дерево на странице. Для этого сделал такой замечательный VF компонент, который вызывает самого себя для вывода всех подчиненных RoleWrappers
ShowRoleWrapper.component
<apex:component >
<apex:attribute name="rws" type="RoleWrapper[]" default="Default value for S attribute" description="test" />
<apex:repeat value="{!rws}" var="rw" >
<div class="level-{!rw.level}">
<div class="role-name">
{!rw.role.Name}
</div>
<c:ShowRoleWrapper rws="{!rw.childRoles}" />
</div>
</apex:repeat>
</apex:component>
на самой VF странице вызов всего одной строчкой<c:ShowRoleWrapper rws="{!roleWrappers}" />
В итоге ошибка:
Cyclic page or component references '/apexcomponent/c__showrolewrapper' are not allowed
Как эту фигню можно победить? Чтобы не писать злые кастыли
[size=85]([i]получилось много текста - в 2-х словах в следующем сообщении[/i])[/size] Сколько лет не хотел использовать VF component ввиду их глючности и ограниченности, но сегодня пришлось. Хотел сделать красиво. В итоге как и ожидалось в самом финале уперся в проблему. Задача: наверное банальнее некуда - построить дерево, например ролей. [i]Обычно такую задачу решаю рендерингом html прямо в контроллере в рекурсивной функции. Но сейчас стоит задача построить дерево с родными input для Salesforce. Чтобы можно было что-то отредактировать для каждой роли и отправить в контроллер на обработку обычным методом.[/i] сделал RoleWrapper для Role__c, который будет содержать List подчиненных ролей (в виде RoleWrappers) для воссоздания иерархической структуры. [code] public with sharing class RoleWrapper { public Role__c role { get; set; } public List<RoleWrapper> childRoles { get; set; } public RoleWrapper(Role__c role) { this.role = role; childRoles = new List<RoleWrapper>(); } } [/code] дерево в рекурсивной функции строится замечательно. Теперь задача вывести это дерево на странице. Для этого сделал такой замечательный VF компонент, который вызывает самого себя для вывода всех подчиненных RoleWrappers ShowRoleWrapper.component [code] <apex:component > <apex:attribute name="rws" type="RoleWrapper[]" default="Default value for S attribute" description="test" /> <apex:repeat value="{!rws}" var="rw" > <div class="level-{!rw.level}"> <div class="role-name"> {!rw.role.Name} </div> <c:ShowRoleWrapper rws="{!rw.childRoles}" /> </div> </apex:repeat> </apex:component> [/code] на самой VF странице вызов всего одной строчкой [code]<c:ShowRoleWrapper rws="{!roleWrappers}" />[/code] В итоге ошибка: [b]Cyclic page or component references '/apexcomponent/c__showrolewrapper' are not allowed[/b] Как эту фигню можно победить? Чтобы не писать злые кастыли
в 2-x словах - в Salesforce нельзя вызывать компонент рекурсивно?
в 2-x словах - в Salesforce нельзя вызывать компонент рекурсивно?
Не знаю, поможет ли это, но вот статья предложенная к изучению Артемом в соседней теме:
https://developer.salesforce.com/page/Dynamic_Visualforce_Components
"Обычно такую задачу решаю рендерингом html прямо в контроллере в рекурсивной функции"
но ведь можно в контроллере вместо HTML таким же образом создать оригинальные ВФ элементы? а это тебе вроде и нужно.
Не знаю, поможет ли это, но вот статья предложенная к изучению Артемом в соседней теме: [url]https://developer.salesforce.com/page/Dynamic_Visualforce_Components[/url] [i]"Обычно такую задачу решаю рендерингом html прямо в контроллере в рекурсивной функции"[/i] но ведь можно в контроллере вместо HTML таким же образом создать оригинальные ВФ элементы? а это тебе вроде и нужно.
Может я не понимаю проблему но зачем было писать компонент,можно сделать два repeater вложенные друг в друга ?
Может я не понимаю проблему но зачем было писать компонент,можно сделать два repeater вложенные друг в друга ?
Я бы еще одну вещь проверил бы компоненты вроде как рендерятся во view state,Мне думается что не есть гуд с работать циклами для компонентов.
Я бы еще одну вещь проверил бы компоненты вроде как рендерятся во view state,Мне думается что не есть гуд с работать циклами для компонентов.
Млин обидно. Я то все время считал что компоненты именно для того и созданы чтобы показывать на странице повторяющиеся части.
[quote]Может я не понимаю проблему но зачем было писать компонент,можно сделать два repeater вложенные друг в друга ?[/quote] 2 repeat вложенный друг в друга - это только 2 уровня. А если уровней N, то я устану эти repeat вкладывать друг в друга [quote]Я бы еще одну вещь проверил бы компоненты вроде как рендерятся во view state,Мне думается что не есть гуд с работать циклами для компонентов.[/quote] Вот это пока не проверял. Но тут вся суть в том что компонент не имеет контроллера, и по логике он не должен поэтому жрать view state. Я только передаю ему через attribute объект, который мне нужно показать. Соотвественно в этом объекте есть еще лист таких же объектов которые точно также надо показать, а в этих объектах тоже есть список таких же объектов которые надо показать, а в этих ... короче так до бесконечности. Млин обидно. Я то все время считал что компоненты именно для того и созданы чтобы показывать на странице повторяющиеся части.
Задачу конечно решил без компонентов, и получилось даже лучше чем я ожидал - лучше чем с компонентами если бы они заработали. Компонентам не зачет.
Задачу конечно решил без компонентов, и получилось даже лучше чем я ожидал - лучше чем с компонентами если бы они заработали. Компонентам не зачет.
[quote="Dmitry Shnyrev"]Задачу конечно решил без компонентов, и получилось даже лучше чем я ожидал - лучше чем с компонентами если бы они заработали. Компонентам не зачет.[/quote] Хорошо что решил просто хотел услышать как ?
Не стал заморачиваться с вложенными inner классами для описания древовидной структуры.
Сделал простой лист из inner классов, но добавил внутрь Integer level значение для задания отступа.
получилось из такого списка:
List<ClassWrapper>
- classWrapper 1 (level 0)
- classWrapper 2 (level 2)
- classWrapper 3 (level 3)
- classWrapper 4 (level 0)
вот такой вид на экране
- classWrapper 1
- classWrapper 2
- classWrapper 3
- classWrapper 4
такое псевдо дерево.
отступы формировались с помощью padding-left: {!20*level}px
вся хитрость как просчитать эти самые levels для classWrapper внутри контроллера. Хотя тут ничего особенного - та же самая рекурсия.
PS. сори если запутанно объяснил. Никогда не получалось объяснить алгоритм с рекурсией. Проще написать, чем объяснить :)
Не стал заморачиваться с вложенными inner классами для описания древовидной структуры. Сделал простой лист из inner классов, но добавил внутрь Integer level значение для задания отступа. получилось из такого списка: List<ClassWrapper> - classWrapper 1 (level 0) - classWrapper 2 (level 2) - classWrapper 3 (level 3) - classWrapper 4 (level 0) вот такой вид на экране [code] - classWrapper 1 - classWrapper 2 - classWrapper 3 - classWrapper 4 [/code] такое псевдо дерево. отступы формировались с помощью padding-left: {!20*level}px вся хитрость как просчитать эти самые levels для classWrapper внутри контроллера. Хотя тут ничего особенного - та же самая рекурсия. PS. сори если запутанно объяснил. Никогда не получалось объяснить алгоритм с рекурсией. Проще написать, чем объяснить :)