无法过滤 Wicket 中的下拉选项
Unable to filter a dropdownchoice in Wicket
我有一个对象 Users,它包含一组另一个对象 Roles。我创建了一个新面板 ListPanel,用于保存用户具有的角色的列表视图。所有这些都包含在一个数据表中。不过,我希望能够过滤该角色列表,这就是我被困的地方。当我尝试过滤 DataTable 上的角色时,出现以下错误:"Could not convert value: Admin to type: java.util.Set. Could not find compatible converter." Admin 是我从下拉列表中获得的值。
我不知道从这里去哪里。根据我的阅读,您不能将 Converter 与 DropDownChoice 一起使用,因此我研究了创建 Renderer 但传递到 Renderer 的值是一个 String 而不是 Role 对象。我认为渲染器是正确的选择,但需要在其他地方进行一些更改才能使其正常工作。
实体
public class User {
private String id;
private String name;
private Set<Role> roles;
......properties/getters/setters.......
}
public class Role {
private String role;
private int active;
......properties/getters/setters.......
}
搜索面板
public class UserSearchPanel extends BreadCrumbPanel {
private static final int ROWS_PER_PAGE = 20;
@Inject
private UserDao userDao;
@Inject
private RoleDao roleDao;
private final UserDataTable dataTable;
public UserSearchPanel( final String id, final IBreadCrumbModel breadCrumbModel ) {
super( id, breadCrumbModel );
NotificationPanel feedback = new NotificationPanel( "feedback" );
feedback.setOutputMarkupId( true );
add( feedback );
UserDataProvider dataProvider = new UserDataProvider( userDao );
dataProvider.setFilterState( loadFilterState() );
// create the form used to contain all filter components
final FilterForm<User> form = new FilterForm<User>( "userSearchForm", dataProvider ) {
@Override
protected void onSubmit() {
dataTable.setCurrentPage( 0 );
}
};
dataTable = new UserDataTable( "dataTable", createColumns(), dataProvider, ROWS_PER_PAGE, this );
dataTable.addTopToolbar( new FilterToolbar( dataTable, form, dataProvider ) );
form.add( dataTable );
add( form );
}
/**
* The columns shown on the page.
*/
private List<IColumn<User, String>> createColumns() {
List<IColumn<User, String>> columns = new ArrayList<IColumn<User, String>>();
List<String> choices = new ArrayList<String>();
try {
choices = roleDao.getAvailableRoles();
} catch ( Exception e ) {
e.printStackTrace();
}
if ( choices.size() > 1 ) {
IModel<List<? extends String>> filterChoices = Model.ofList( choices );
columns.add( createChoiceColumn( "datatable.roles.label", "roles", "roles", filterChoices ) );
}
return columns;
}
private ChoiceFilteredPropertyColumn<User, String, String> createChoiceColumn( final String key, final String sortProperty, final String propertyExpression, final IModel<List<? extends String>> filterChoices ) {
IModel<String> label = getLabel();
return new ChoiceFilteredPropertyColumn<User, String, String>( label, sortProperty, propertyExpression, filterChoices ) {
@Override
protected boolean enableAutoSubmit() {
return false;
}
@Override
public void populateItem( Item<ICellPopulator<User>> cellItem, String componentId, IModel<User> rowModel ) {
cellItem.add( new ListPanel( componentId, rowModel ) );
}
};
}
private class ListPanel extends Panel {
public ListPanel( String id, IModel<User> model ) {
super( id );
User user = (User) model.getObject();
addList( user );
}
private void addList( User user ) {
Set<Role> rolesSet = user.getRoles();
List<Role> roles = new ArrayList<>();
for ( Role role : rolesSet ) {
roles.add( role );
}
ListView<Role> view = new ListView<Role>( "list", roles ) {
@Override
protected void populateItem( ListItem<Role> item ) {
final Role role = (Role) item.getModelObject();
item.add( new Label( "roles", role.getRole() ) );
}
};
add( view );
}
}
}
我建议您创建一个 class,而不是使用您的 User
对象,它表示您要过滤的内容并对 IDataProvider
中的这些值做出反应。
当前发生的情况是您正在使用用户对象来表示您的 FilterState
并且 wicket 尝试将字符串 "ADMIN" 设置为 [=11= 的 Set<Role>
] 对象。
只需在单独的对象中声明不同的过滤器选项。
喜欢:
class FilterState implements Serializable {
private String roles;
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
}
class UserDataProvider implements IDataProvider<User>, IFilterStateLocator<FilterState> {
private FilterState state;
private UserDao userDao;
public UserDataProvider() {
state = new FilterState();
}
....
@Override
public Iterator<? extends User> iterator(long first, long count) {
//just some example filter logic, handled by the dao
if (state == null || state.getRoles() == null) {
return userDao.getUserList(first, count).iterator();
} else {
return userDao.getUserListByRoleName(state.getRoles(), first, count).iterator();
}
}
@Override
public FilterState getFilterState() {
return state;
}
@Override
public void setFilterState(FilterState state) {
this.state = state;
}
}
我有一个对象 Users,它包含一组另一个对象 Roles。我创建了一个新面板 ListPanel,用于保存用户具有的角色的列表视图。所有这些都包含在一个数据表中。不过,我希望能够过滤该角色列表,这就是我被困的地方。当我尝试过滤 DataTable 上的角色时,出现以下错误:"Could not convert value: Admin to type: java.util.Set. Could not find compatible converter." Admin 是我从下拉列表中获得的值。
我不知道从这里去哪里。根据我的阅读,您不能将 Converter 与 DropDownChoice 一起使用,因此我研究了创建 Renderer 但传递到 Renderer 的值是一个 String 而不是 Role 对象。我认为渲染器是正确的选择,但需要在其他地方进行一些更改才能使其正常工作。
实体
public class User {
private String id;
private String name;
private Set<Role> roles;
......properties/getters/setters.......
}
public class Role {
private String role;
private int active;
......properties/getters/setters.......
}
搜索面板
public class UserSearchPanel extends BreadCrumbPanel {
private static final int ROWS_PER_PAGE = 20;
@Inject
private UserDao userDao;
@Inject
private RoleDao roleDao;
private final UserDataTable dataTable;
public UserSearchPanel( final String id, final IBreadCrumbModel breadCrumbModel ) {
super( id, breadCrumbModel );
NotificationPanel feedback = new NotificationPanel( "feedback" );
feedback.setOutputMarkupId( true );
add( feedback );
UserDataProvider dataProvider = new UserDataProvider( userDao );
dataProvider.setFilterState( loadFilterState() );
// create the form used to contain all filter components
final FilterForm<User> form = new FilterForm<User>( "userSearchForm", dataProvider ) {
@Override
protected void onSubmit() {
dataTable.setCurrentPage( 0 );
}
};
dataTable = new UserDataTable( "dataTable", createColumns(), dataProvider, ROWS_PER_PAGE, this );
dataTable.addTopToolbar( new FilterToolbar( dataTable, form, dataProvider ) );
form.add( dataTable );
add( form );
}
/**
* The columns shown on the page.
*/
private List<IColumn<User, String>> createColumns() {
List<IColumn<User, String>> columns = new ArrayList<IColumn<User, String>>();
List<String> choices = new ArrayList<String>();
try {
choices = roleDao.getAvailableRoles();
} catch ( Exception e ) {
e.printStackTrace();
}
if ( choices.size() > 1 ) {
IModel<List<? extends String>> filterChoices = Model.ofList( choices );
columns.add( createChoiceColumn( "datatable.roles.label", "roles", "roles", filterChoices ) );
}
return columns;
}
private ChoiceFilteredPropertyColumn<User, String, String> createChoiceColumn( final String key, final String sortProperty, final String propertyExpression, final IModel<List<? extends String>> filterChoices ) {
IModel<String> label = getLabel();
return new ChoiceFilteredPropertyColumn<User, String, String>( label, sortProperty, propertyExpression, filterChoices ) {
@Override
protected boolean enableAutoSubmit() {
return false;
}
@Override
public void populateItem( Item<ICellPopulator<User>> cellItem, String componentId, IModel<User> rowModel ) {
cellItem.add( new ListPanel( componentId, rowModel ) );
}
};
}
private class ListPanel extends Panel {
public ListPanel( String id, IModel<User> model ) {
super( id );
User user = (User) model.getObject();
addList( user );
}
private void addList( User user ) {
Set<Role> rolesSet = user.getRoles();
List<Role> roles = new ArrayList<>();
for ( Role role : rolesSet ) {
roles.add( role );
}
ListView<Role> view = new ListView<Role>( "list", roles ) {
@Override
protected void populateItem( ListItem<Role> item ) {
final Role role = (Role) item.getModelObject();
item.add( new Label( "roles", role.getRole() ) );
}
};
add( view );
}
}
}
我建议您创建一个 class,而不是使用您的 User
对象,它表示您要过滤的内容并对 IDataProvider
中的这些值做出反应。
当前发生的情况是您正在使用用户对象来表示您的 FilterState
并且 wicket 尝试将字符串 "ADMIN" 设置为 [=11= 的 Set<Role>
] 对象。
只需在单独的对象中声明不同的过滤器选项。
喜欢:
class FilterState implements Serializable {
private String roles;
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
}
class UserDataProvider implements IDataProvider<User>, IFilterStateLocator<FilterState> {
private FilterState state;
private UserDao userDao;
public UserDataProvider() {
state = new FilterState();
}
....
@Override
public Iterator<? extends User> iterator(long first, long count) {
//just some example filter logic, handled by the dao
if (state == null || state.getRoles() == null) {
return userDao.getUserList(first, count).iterator();
} else {
return userDao.getUserListByRoleName(state.getRoles(), first, count).iterator();
}
}
@Override
public FilterState getFilterState() {
return state;
}
@Override
public void setFilterState(FilterState state) {
this.state = state;
}
}