【问题标题】:getting a spring model attribute list element using an index from javascript使用来自 javascript 的索引获取 spring 模型属性列表元素
【发布时间】:2012-11-01 18:37:33
【问题描述】:

很抱歉,如果在其他地方问过这个问题,但我环顾四周,找到了一些答案,但不是一个完整的例子,我仍然对这个有疑问。

所以,我将 Spring 控制器中的自动填充列表添加到我的 jsp 中,并且我想在我的 javascript/jquery 函数内的列表中添加项目。可能吗?

我尝试了下面的代码来测试功能,但它不起作用(列表元素根本没有显示在生成的 html 中)。所以我不确定是我弄乱了 javascrit/spring/jsp 语法还是不可能。

代码如下:

控制器代码:

@RequestMapping(value="/create_custobject.html",method = RequestMethod.GET)
public ModelAndView showCreateCustObjectPage() {
    Map<String, Object> model = new HashMap<String, Object>();

    CreateObjectForm form = new CreateObjectForm();
    model.put("createObjectform", form);

    return new ModelAndView("create_custobject", model) ;

}

表格代码:

public class CreateObjectForm {

      private AutoPopulatingList<Criteria> ruleArray = new AutoPopulatingList<Criteria>(Criteria.class);

     public AutoPopulatingList<Criteria> getRuleArray() {
    return ruleArray;
        }

         public void setRuleArray(AutoPopulatingList<Criteria> ruleArray) {
    this.ruleArray = ruleArray;
        }

         public CreateObjectForm() {}
      }

标准代码:

public class Criteria{

   String attribute;

    String operator;
       //... constructor + getters and setters
}

javascript/jquery 代码(与 jsp 位于同一页面):

<script type="text/javascript">
$(document).ready(function(){
    //startup functionality

 var i = 0;
 document.getElementById("addCriteria").onclick = function() {

         $("#msgid").html("${ruleArray[i].attribute}");

        ${ruleArray[i].attribute} = $('#attributeValue').val();             
        ${ruleArray[i].operator} = $('#operatorValue').val(); 

                    i++;            

      }
   }

【问题讨论】:

  • 在 onclick 函数中增加 i 没有任何意义。你的意图是什么?

标签: java javascript jquery spring spring-mvc


【解决方案1】:

您不正确地混合 JSP EL 和 Javascript。您不能在 JSP 表达式中使用 var i,即。 ${ruleArray[i].operator}。我建议使用 JSTL 遍历列表并在脚本中创建属性。

此时,您的脚本可以设置为仅在表达式中使用字符串文字 0。我假设您需要比这更强大的功能,您能更好地描述它吗?

$(document).ready(function(){
     document.getElementById("addCriteria").onclick = function() {

     $("#msgid").html("${ruleArray[0].attribute}");

     //I assume you wanted to set the element to the value pulled from JSP EL
     $('#attributeValue').val(${ruleArray[0].attribute});           
     $('#operatorValue').val(${ruleArray[0].operator});           

     }
 }

使用 JSTL 的解决方案类似于:

<script>
 var criteria = [];
 <c:forEach var="criteria" items=${ruleArray}>
    criteria.push({attr:${criteria.attribute}, oper: ${criteria.operator});
 </c:forEach>

 for(var i = 0; i < criteria.length; i++){
  alert(criteria[i].attribute);
 }
</script>

这个方案基本上是用JSTL来写Javascript的。修改控制器以返回 JSON 并在页面加载时进行 Ajax 调用可能是更好的解决方案。

【讨论】:

  • 我稍微清理了代码(添加了“i”迭代),但基本上我想在 javascript 代码的自动填充列表中添加新项目,并在发布时获取列表已经完成了。我不能在 javascript 中使用 jstl 对吗?
  • @Thomas:不,如果您希望代码在客户端执行,则不能。
【解决方案2】:

在以下行中,您在 jsp 代码中引用 i,但未定义 i:

$("#msgid").html("${ruleArray[i].attribute}");

定义i 的javascript 代码在客户端(即浏览器)上执行。 jsp 代码在服务器上执行,然后将呈现的 html 发送到客户端。

【讨论】:

    【解决方案3】:

    对于表单中的现有项目,使用 jstl as

    <c:forEach items="${form.items}" var="item" varStatus="status" >
    <span class="count" > 
    <form:input   path="items[${status.index}].field" />
    

    这将呈现这样的表单

    <form id = "idform" >
    <span class="count" > 
        <input   name="items[0].field"  id="items0.field" />
    </span>
    </form>
    

    然后您只需使用 javascript 添加具有对应索引的新表单“行”

    例如

     var is = $('.count').size()
     $('#idform span:last').after('<span class="count" ><input name="items[' + is + '].field"' + is + '.field" /></span>')
    

    我认为如果你使用的是 spring 3 + 你不需要使用 AutopopulatingList ,任何集合都应该足够了。

    【讨论】:

      【解决方案4】:

      即使这个帖子较旧并且回答正确,为了其他初学者的利益,也为了解释逻辑以实现删除添加的行。

      让我用一个最小的代码和用户示例来解释 firstName、email、userName 和 gender 字段。
      考虑到您从控制器发送用户列表中的 3 个空用户,这将创建 3 个空行。现在您要添加行并将添加的行动态绑定到 modelAttribute。

      (如果是最初的 3 行)如果您检查/查看页面源代码,您将看到

      • 具有不同 id 的行(&lt;input&gt; tags),例如 list0.firstName list1.firstName
      • 具有不同名称的行(&lt;input&gt; tags),例如list[0].firstName list[1].firstName

      每当提交表单时,服务器不会考虑 id 的(添加仅用于帮助客户端验证),但 name 属性 将被解释为请求参数并用于构造你的modelAttribute,因此属性名称在插入行时非常重要。

      添加行

      那么,如何构造/追加新行?
      如果我从 UI 提交 6 个用户,控制器应该从 usersList 接收 6 个用户对象。下面给出了实现相同的步骤
      1、右键-&gt;查看页面源代码。你会看到这样的行(你可以在第一行看到*[0].*,在第二行看到*[1].*

      <tr>
          <td><input id="list0.firstName" name="list[0].firstName" type="text" value=""/></td>
          <td><input id="list0.email" name="list[0].email" type="text" value=""/></td>
          <td><input id="list0.userName" name="list[0].userName" type="text" value=""/></td>
          <td>
              <span>
                  <input id="list0.gender1" name="list[0].gender" type="radio" value="MALE" checked="checked"/>Male
              </span>
              <span>
                  <input id="list0.gender2" name="list[0].gender" type="radio" value="FEMALE"/>Female
              </span>
          </td>
      </tr>
      
      <tr>
          <td><input id="list1.firstName" name="list[1].firstName" type="text" value=""/></td>
          <td><input id="list1.email" name="list[1].email" type="text" value=""/></td>
          <td><input id="list1.userName" name="list[1].userName" type="text" value=""/></td>
          <td>
              <span>
                  <input id="list1.gender1" name="list[1].gender" type="radio" value="MALE" checked="checked"/>Male
              </span>
              <span>
                  <input id="list1.gender2" name="list[1].gender" type="radio" value="FEMALE"/>Female
              </span>
          </td>
      </tr>
      
      1. 复制第一行并构造一个 javascript 字符串并将“0”替换为变量名索引。如下示例所示
      '<tr>'+
          '<td><input id="list'+ index +'.firstName" name="list['+ index +'].firstName" type="text" value=""/></td>'+
          '<td><input id="list'+ index +'.email" name="list['+ index +'].email" type="text" value=""/></td>'+
          ...
      '</tr>';
      
      1. 将构造的行附加到&lt;tbody&gt;。在 UI 中添加行也会在提交表单时在控制器中接收新添加的行。

      删除行

      删除行有点复杂,我会尝试用最简单的方式解释

      • 假设您添加了 row0、row1、row2、row3、row4、row5
      • 已删除第 2 行、第 3 行。不要只是隐藏该行,而是将其从 DOM 通过捕获事件。
      • 现在 row0,row1,row4,row5 将被提交,但在控制器中您的 userList 将有 6 个用户对象,但 user[2].firstName 将为 null 并且 user[3].firstName 将为空。
      • 因此在您的控制器中迭代并检查 null 并删除 用户。(使用迭代器不要使用 foreach 删除用户对象)

      发布代码,让初学者受益。

      //  In Controller
      @RequestMapping(value = "/app/admin/add-users", method = RequestMethod.GET)
      public String addUsers(Model model, HttpServletRequest request)
      {
          List<DbUserDetails> usersList = new ArrayList<>();
      
          ListWrapper userListWrapper = new ListWrapper();
          userListWrapper.setList(usersList);
      
      
          DbUserDetails user;
          for(int i=0; i<3;i++)
          {
              user = new DbUserDetails();
              user.setGender("MALE"); //Initialization of Radio button/ Checkboxes/ Dropdowns
              usersList.add(user);
          }
      
      
          model.addAttribute("userListWrapper", userListWrapper);
          model.addAttribute("roleList", roleList);
      
          return "add-users";
      }
      
      @RequestMapping(value = "/app/admin/add-users", method = RequestMethod.POST)
      public String saveUsers(@ModelAttribute("userListWrapper") ListWrapper userListWrapper, Model model, HttpServletRequest request)
      {
          List<DbUserDetails> usersList = userListWrapper.getList();
          Iterator<DbUserDetails> itr = usersList.iterator();
      
          while(itr.hasNext())
          {
              if(itr.next().getFirstName() == null)
              {
                  itr.remove();
              }
          }
      
          userListWrapper.getList().forEach(user -> {
              System.out.println(user.getFirstName());
          });
          return "add-users";
      }
      
      //POJO
      @Entity
      @Table(name = "userdetails")
      @XmlRootElement(name = "user")
      public class DbUserDetails implements Serializable
      {
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private Integer id;
          private String  firstName;
          private String  userName;
          private String  email;
          private String  gender;
      
          //setters and getters
      }
      
      //list wrapper
      public class ListWrapper
      {
          private List<DbUserDetails> list;
      
          //setters and getters
      }
      

      在 JSP 中

      <form:form method="post" action="${pageContext.request.contextPath}/app/admin/add-users" modelAttribute="userListWrapper">
          <table class="table table-bordered">
              <thead>
                  <tr>
                      <th><spring:message code="app.userform.firstname.label"/></th>
                      <th><spring:message code="app.userform.email.label"/></th>
                      <th><spring:message code="app.userform.username.label"/></th>
                      <th><spring:message code="app.userform.gender.label"/></th>
                  </tr>
              </thead>
              <tbody id="tbodyContainer">
                  <c:forEach items="${userListWrapper.list}" var="user" varStatus="loop">
                      <tr>
                          <td><form:input path="list[${loop.index}].firstName" /></td>
                          <td><form:input path="list[${loop.index}].email" /></td>
                          <td><form:input path="list[${loop.index}].userName" /></td>
                          <td>
                              <span>
                                  <form:radiobutton path="list[${loop.index}].gender" value="MALE" /><spring:message code="app.userform.gender.male.label"/>
                              </span>
                              <span>
                                  <form:radiobutton path="list[${loop.index}].gender" value="FEMALE" /><spring:message code="app.userform.gender.female.label"/>
                              </span>
                          </td>
                      </tr>
                  </c:forEach>
              </tbody>
          </table>
          <div class="offset-11 col-md-1">
              <button type="submit" class="btn btn-primary">SAVE ALL</button>     
          </div>
      </form:form>
      

      Javascript 需要包含在 JSP 中

      var currentIndex = 3; //equals to initialRow (Rows shown on page load)
      function addRow()
      {
          var rowConstructed = constructRow(currentIndex++);
          $("#tbodyContainer").append(rowConstructed);
      }
      
      function constructRow(index)
      {
          return '<tr>'+
          '<td><input id="list'+ index +'.firstName" name="list['+ index +'].firstName" type="text" value=""/></td>'+
          '<td><input id="list'+ index +'.email" name="list['+ index +'].email" type="text" value=""/></td>'+
          '<td><input id="list'+ index +'.userName" name="list['+ index +'].userName" type="text" value=""/></td>'+
          '<td>'+
              '<span>'+
                  '<input id="list'+ index +'.gender1" name="list['+ index +'].gender" type="radio" value="MALE" checked="checked"/>Male'+
              '</span>'+
              '<span>'+
                  '<input id="list'+ index +'.gender'+ index +'" name="list['+ index +'].gender" type="radio" value="FEMALE"/>Female'+
              '</span>'+
          '</td>'+
      '</tr>';
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-15
        相关资源
        最近更新 更多