Vaadin 使用不同的 id 和数据绑定制作动态 RadioButtonGroup?

Vaadin making dynamic RadioButtonGroup with different id and databinding?

我有一个单选按钮动态组的用例,例如 Q/A 表单,问题描述和答案作为单选按钮 Yes/No:

我从后端获取 questionDescription 作为列表并对其进行迭代以生成标签和 RadioButtonGroup。

private Card createCard(QuestionGroup questionGroup) {
    VerticalLayout desc = new VerticalLayout();
    desc.setSpacing(false);
    System.out.println("question :" +questionGroup.getQuestions().size());
    for (Question question : questionGroup.getQuestions()) {
        desc.add(createIndividualElement(question.getQuestionDesc(), questionGroup.getQuestionDesc(),
                question.getId()));
    }

  .......

    Card card = new Card(cardHeader, desc);
    card.setWidth("100%");

    return card;
}

private HorizontalLayout createIndividualElement(String desc, String groupHeader, Integer id) {
    HorizontalLayout content = new HorizontalLayout();
    content.addClassName("cardContentLayout");
    content.addAndExpand(new Label(desc));

    RadioButtonGroup<Question.Answer> radioGroup = new RadioButtonGroup<>();
    radioGroup.setId(groupHeader + id);
    radioGroup.setItems(Question.Answer.values());
    radioGroup.setValue(Question.Answer.NA);
    content.add(radioGroup);
    return content;
}

我不确定如何为这个用例使用活页夹, 有没有办法通过 radioButton 的 Id 获取元素,或者有没有办法使用 Binder 在 form Edit action 上设置 radioButton 的值?

Binder 的想法是绑定到单个 bean 的特定属性(更一般地说:绑定到 getter/setter 对)。在这种情况下,您的 bean 似乎是 QuestionGroup。我假设 answerQuestion:

的 属性
public class Question {
 enum Answer {YES, NO, NA}
 String questionDescription;
 Answer answer;
 //getters, setters...
}

如果每个问题都是 bean 的非动态 属性,则相同的 Binder 对任何 QuestionGroup 都适用,因为它们都有相同的问题:

public class QuestionGroup {
  Question question1;
  Question question2;  
  //getters, setters...
};

那么可以这样做:

binder.forField(radioGroup)
  .asRequired()
  .bind(
    group->group.getQuestion1().getAnswer(), 
    (group,answer)->group.getQuestion1().setAnswer(answer)
  );    

但是,对于您的情况,group.getQuestion1() 没有替代品,因为问题列表取决于问题组本身。 有了这个约束,绑定将特定于给定的 QuestionGroup(不同的 QuestionGroup 将有一组不同的问题,因此您需要重新创建 Binder) 因此,可以假设当前的 group 实例在任何地方都被使用,并且只绑定每个 Question:

    Binder<QuestionGroup> binder = new Binder<>();

    for (Question question : questionGroup.getQuestions()) {
      RadioButtonGroup<Question.Answer> radioGroup = new RadioButtonGroup<>();
      radioGroup.setLabel(question.getQuestionDescription());
      radioGroup.setItems(Question.Answer.values());
      radioGroup.setValue(Question.Answer.NA);       
      binder.forField(radioGroup)
        .asRequired()
        .bind(group->question.getAnswer(), (group,answer)->question.setAnswer(answer));      
      add(radioGroup);
    }

    binder.setBean(questionGroup);

    add(new Button("Save", ev->{
      if (binder.validate().isOk()) {
        //Save questionGroup
        for (Question question : questionGroup.getQuestions()) {
          System.out.println(question.getQuestionDescription()+" "+question.getAnswer());
        }
      }
    }));