我有一个用于编辑bean的网格,这些bean已为其实现了JSR-303 bean级(跨字段)验证。因为BeanValidationBinder不支持Bean级验证,所以我们有自己的实现来验证这些跨字段约束并在无效字段上显示验证错误消息。
现在,这在其他用例上对我们来说很好,但是现在我在显示网格编辑器内字段的错误消息时遇到了问题。
这是一个简化的示例,其中单击“保存”按钮时将验证所有行。如果产品名称不是“产品”,则发现该名称无效。仅处理遇到的第一个错误,这很好。
看起来全部归结为productGrid.getEditor()。editItem(p)-调用validate(列出产品)-方法。如果我将其保留,则错误消息将显示在当前可编辑字段中。当然,那可能不是包含无效数据的那个。
起初,我确实尝试了一种更优雅的解决方案,即用户无法离开无效的行,但是现在,如果我能使它正常运行,我将准备解决该问题。我们在原始代码中使用了BenValidationBinder,它处理了单字段JSR-303验证。
我已通过如下所示编辑MainView类,使用最新的“ Project Base”应用程序启动器(https://vaadin.com/start/latest/project-base)创建了示例代码。与Vaadin版本13.0.3一起运行
还有其他人遇到过同样的问题,希望能解决这个问题吗?
@Route("")
@PWA(name = "Project Base for Vaadin Flow", shortName = "Project Base")
public class MainView extends VerticalLayout {
private Grid<Product> productGrid;
private TextField code = new TextField();
private TextField name= new TextField();
public MainView() {
List<Product> products = Arrays.asList(new Product("1", "Product"), new Product("2", "Product"));
productGrid = new Grid<MainView.Product>();
productGrid.addColumn(Product::getCode)
.setHeader("Product code")
.setFlexGrow(1);
productGrid.addColumn(Product::getName)
.setEditorComponent(name)
.setHeader("Product name")
.setFlexGrow(1);
Binder<Product> binder = new Binder<>(Product.class);
binder.bindInstanceFields(this);
productGrid.getEditor().setBinder(binder);
productGrid.addItemClickListener(event -> productGrid.getEditor().editItem(event.getItem()));
productGrid.setItems(products);
Button save = new Button("Save",
event -> save(products));
add(save);
add(productGrid);
}
private void save(List<Product> products) {
if(validate(products)) {
Notification.show("Saved: " + String.join(", ", products.stream().map(Product::toString).collect(Collectors.toList())));
}else {
Notification.show("Invalid data");
}
}
private boolean validate(List<Product> products) {
// this only mocks the JSR-303 validation call
for(Product p:products) {
if(!p.getName().equals("Product")) {
productGrid.getEditor().editItem(p);
name.setErrorMessage("Invalid name, should be: Product");
name.setInvalid(true);
return false;
}
}
return true;
}
public class Product{
String code;
String name;
public Product(String code, String name) {
super();
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return code + " " + name;
}
}
}