2015-02-07 4 views
0

В нашем приложении у нас есть различные поля выбора. Содержимое полей выбора всегда заполняется значениями из базы данных, например, селектор currency будет содержать валюты, добавленные в базу данных, или User. Объекты могут выбираться в зависимости от роли определенных пользователей.JSF Select Menu, дескриптор удаленных значений

Проблема в том, что эти данные могут меняться со временем, но старые экземпляры, использующие эти значения, должны оставаться нетронутыми. Если пользователь теперь пикетирует leadDeveloper, из-за его ролей, но он покинул компанию, список выбора больше не содержит этого пользователя, поэтому в поле выбора теперь будет отображаться опция no-select, потому что источник списка больше не содержать элемент.

Есть ли хороший способ обойти эту проблему?

Конкретный пример:

Java:

@Named 
@ViewScoped 
public class MyBean{ 

    public List<IKeyValuePair> getAvailableDeveloper(){ 
     // everything available to select-fields is implementing 
     // iKeyValuePair, most the time used as id/name, depending on entity 
     return userDataService.getUsersWithRole("developer"); 
    } 
} 

public class User implements IKeyValuePair{ 

    //properties 

    @Override 
    public string getKey(){ 
     //use id 
     return this.id.toString(); 
    } 

    @Override 
    public string getValue(){ 
     //use lastname, firstname 
     return this.lastname + ", " + this.firstname; 
    } 
} 

XHTML:

<p:selectOneMenu value="#{project.leadDeveloper}" style="width:125px" readonly="#{project.closed}"> 
     <f:selectItem itemLabel="Select One" itemValue="" /> 
     <f:selectItems value="#{myBean.availableDevelopers}" var="dev" 
      itemLabel="#{dev.getValue()}" itemValue="#{dev.getKey()}" /> 
</p:selectOneMenu> 

Теперь пользователь будет выбран из этого списка - скажем алиса. Отныне исторический взгляд на этот проект покажет alice как выбранный разработчик в отключенном selectOneMenu, как только проект закончится.

2 года спустя Алиса покинула компанию, поэтому ее роль разработчик был отозван. getAvailableDeveloper() больше не будет содержать alice, и поэтому выбранное значение больше не является частью источника данных. Поле выбора теперь будет показывать Выберите один.

Я мог бы вручную убедиться, что пользователь, о котором идет речь, добавлен в список для целей истории (если отсутствует) - однако это было бы что-то, что мне нужно было бы реализовать case-by-case в соответствующем методе getter, в зависимости от по типу объекта.

Было бы лучше, если бы это можно было обработать автоматическим способом внутри (настраиваемого) рендерера selectOneMenu. Но прежде чем я пойду туда, я хотел бы спросить, есть ли лучшие решения на эту тему.

ps .: Код не является точной копией, просто наглядным примером для описания проблемы.

+0

На первый взгляд это похоже на то, что вы должны обрабатывать в своем слое данных, где вы должны удалять свои сущности и все дерево зависимых объектов – kolossus

ответ

0

Я, наконец, решил его, позвонив каждому человеку getter через прокси-метод, который заботится о оставшейся работе.

Вместо

public List<IKeyValuePair> getAvailableDeveloper(){ 
    // everything available to select-fields is implementing 
    // iKeyValuePair, most the time used as id/name, depending on entity 
    return userDataService.getUsersWithRole("developer"); 
} 

вместе с разметкой

<f:selectItems value="#{myBean.availableDevelopers}" var="dev" 
     itemLabel="#{dev.getValue()}" itemValue="#{dev.getKey()}" /> 

Я кончался называть «общий» метод, передавая текущий выбор и фактический список и, наконец, добавив этот выбор, чтобы возвращаемый если нет:

<f:selectItems value="#{myBean.proxyForLists(myBean.availableDevelopers, currentElement)}" var="dev" 
     itemLabel="#{dev.getValue()}" itemValue="#{dev.getKey()}" /> 

и прокси-метод

public List<IKeyValuePair> proxyForLists(List<IKeyValuePair> source, Object selection){ 

    if (selection == null) return source; 

    if (selection instanceof User){ 
     User selectedUser = (User) selection; 
     KeyValuePair kvp = new KeyValuePair(selectedUser.getShortName(), selectedUser); 
     if (!source.contains(kvp)){ 
      source.add(kvp); 
     } 
    } 
    //other types handled as well. 
    return source; 
} 

Таким образом, всякий раз, когда выбранное значение A больше не входит в список источников, он добавляется методом прокси, что делает выберите поле, способное показать его снова. Для «новых» созданий A больше не является частью исходного списка, поэтому пользователь больше не может выбирать A.

Смежные вопросы