Почему эти два одинаковых рекурсивных C-кода дают разные результаты?

Основываясь на истории вопроса, вы используете JSF 2.x. Итак, вот целевой запрос JSF 2.x. В JSF 1.x вам придется переносить значения / метки элемента в уродливые экземпляры SelectItem . Это, к счастью, больше не требуется в JSF 2.x.


Основной пример

Чтобы ответить на ваш вопрос напрямую, просто используйте value указывает на свойство List, которое вы сохраняете из БД во время построения столбца (столбца). Вот пример базового запуска, предполагающий, что T фактически представляет String.


    

с

@ManagedBean
@RequestScoped
public class Bean {

    private String name;
    private List names; 

    @EJB
    private NameService nameService;

    @PostConstruct
    public void init() {
        names = nameService.list();
    }

    // ... (getters, setters, etc)
}

Простой. Фактически, T 's toString() будет использоваться для представления как ярлыка выпадающего элемента, так и значения. Итак, когда вы вместо List используете список сложных объектов, таких как List, и вы не переопределили метод класса toString(), вы увидите com.example.SomeEntity@hashcode как значения элемента. См. Следующий раздел, как правильно его решить.

Также обратите внимание, что bean для значения необязательно должен быть одним и тем же компонентом, что и bean для значения . Это полезно, когда значения фактически являются общими константами, которые вам просто нужно загружать только один раз во время запуска приложения. Тогда вы могли бы просто сделать это свойством компонента с областью приложения.


    


Сложные объекты как доступные элементы

Всякий раз, когда T относится к сложному объекту (javabean ), например User, который имеет свойство String в name, тогда вы можете использовать атрибут var для получения переменной итерации, которую вы, в свою очередь, можете использовать в itemValue и / или itemLabel ] присваивает (если вы опускаете itemLabel, тогда метка становится той же, что и значение).

Пример # 1:


    

с

private String userName;
private List users;

@EJB
private UserService userService;

@PostConstruct
public void init() {
    users = userService.list();
}

// ... (getters, setters, etc)

Или когда у него есть свойство Long, которое вы хотели бы задать как значение элемента:

Пример # 2:


    

с

private Long userId;
private List users;

// ... (the same as in previous bean example)

Сложный объект как выделенный элемент

Всякий раз, когда вы хотите установить его в свойство T в bean-а также, а T представляет User ], вам нужно будет испечь пользовательский Converter , который преобразует между User и уникальным строковым представлением (которое может быть свойством id). Обратите внимание, что itemValue должен представлять сам сложный объект, именно тот тип, который необходимо установить в качестве компонента выделения value.


    

с

private User user;
private List users;

// ... (the same as in previous bean example)

и

@ManagedBean
@RequestScoped
public class UserConverter implements Converter {

    @EJB
    private UserService userService;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        if (submittedValue == null || submittedValue.isEmpty()) {
            return null;
        }

        try {
            return userService.find(Long.valueOf(submittedValue));
        } catch (NumberFormatException e) {
            throw new ConverterException(new FacesMessage(String.format("%s is not a valid User ID", submittedValue)), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        if (modelValue == null) {
            return "";
        }

        if (modelValue instanceof User) {
            return String.valueOf(((User) modelValue).getId());
        } else {
            throw new ConverterException(new FacesMessage(String.format("%s is not a valid User", modelValue)), e);
        }
    }

}

(обратите внимание, что Converter немного взломан, чтобы иметь возможность вставлять @EJB в конвертер JSF, обычно он должен был бы аннотировать его как @FacesConverter(forClass=User.class), , но, к сожалению, не позволяет @EJB инъекции )

Не забудьте убедиться, что класс сложного объекта имеет equals() и hashCode() должным образом реализованы , в противном случае JSF во время рендеринга не сможет отобразить предварительно выбранный элемент (ы), и вы отправите face Ошибка проверки: значение недействительно .

public class User {

    private Long id;

    @Override
    public boolean equals(Object other) {
        return (other != null && getClass() == other.getClass() && id != null)
            ? id.equals(((User) other).id)
            : (other == this);
    }

    @Override
    public int hashCode() {
        return (id != null) 
            ? (getClass().hashCode() + id.hashCode())
            : super.hashCode();
    }

}

Сложные объекты с общим конвертером

Голосовать до этого ответа: Реализовывать преобразователи для объектов с Java Generics .

Сложные объекты без пользовательского конвертера

Библиотека утилиты JSF OmniFaces предлагает специальный конвертер из окна, который позволяет y ou использовать сложные объекты в без необходимости создания настраиваемого конвертера. SelectItemsConverter просто выполнит преобразование на основе легко доступных элементов в .


    


См. Также:

1
задан ripfreeworld 15 January 2019 в 21:39
поделиться

1 ответ

Когда вы объявляете параметр int c во втором func, он затеняет глобальный c, поэтому все дальнейшие изменения в рамках функции применяются только к локальному c вместо глобального.

0
ответ дан 0x5453 15 January 2019 в 21:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: