从JSP列表中填充JavaScript数组

14

好的,也许有人可以帮我解决一个问题。本质上,我有一个 JSP 页面,从 Spring Portlet SimpleFormController 的 referenceData() 方法获取了一个 Country 对象列表(不完全相关但提一下以防需要)。每个 Country 对象都有一组省份对象,每个省份和国家都有一个名称字段:

public class Country  {
    private String name;
    private Set<Province> provinces;

    //Getters and setters
}

public class Province {
    private String name;

    //Getters and setters
}

我现在有两个下拉菜单,一个用于选择国家,一个用于选择省份,我想通过国家来过滤省份。我一直在按照这个教程/指南 使用JavaScript制作链式选择。

现在我需要一种动态的方式从我的内容中创建JavaScript数组。在有人提到AJAX之前,我必须指出这是不可能的,因为我们的项目使用portlet,并且希望避免使用像DWR这样的框架或创建servlet。这是我目前拥有的JavaScript/JSP代码,但它没有将任何内容填入数组中:

var countries = new Array();
<c:forEach items="${countryList}" var="country" varStatus="status">
    countries[status.index] = new Array();
    countries[status.index]['country'] = ${country.name};
    countries[status.index]['provinces'] =
    [
        <c:forEach items="${country.provinces}" var="province" varStatus="provinceStatus">
            '${province.name}'
            <c:if test="${!provinceStatus.last}">
              ,
            </c:if>
        </c:forEach>
    ];
</c:forEach>

有人知道如何在JSP中创建JavaScript数组吗?或者在这种情况下被认为是“最佳实践”是什么?先感谢了!

4个回答

23
var countries = new Array();
<c:forEach items="${countryList}" var="country" varStatus="status"> 
    countryDetails = new Object();
    countryDetails.country = ${country.name}; 
    var provinces = new Array();

        <c:forEach items="${country.provinces}" var="province" varStatus="provinceStatus"> 
           provinces.push(${province.name});
        </c:forEach> 
    countryDetails.provinces = provinces;
    countries.push(countryDetails);
</c:forEach> 

现在你在JavaScript中所拥有的东西类似于这样

var countries = [
  {country:"USA",
  provinces: [
    "Ohio",
    "New York",
    "California"
  ]},
  {country:"Canada",
  provinces: [
    "Ontario",
    "Northern Territory",
    "Sascetchewan"
  ]},
]
另一个选择是让你的输出看起来像我发布的JavaScript代码。
var countries = [
<c:forEach items="${countryList}" var="country" varStatus="status">  
    {country: '${country.name}',
    provinces : [ 
        <c:forEach items="${country.provinces}" var="province" varStatus="provinceStatus">  
           '${province.name}'
           <c:if test="${!provinceStatus.last}">    
             ,    
           </c:if>   
        </c:forEach>  
    ]}
    <c:if test="${!status.last}">    
      ,    
    </c:if>  
    </c:forEach>  
];

2
第二种方法会生成更少的代码,所以我肯定会选择这种方法。 - Pointy
太好了,谢谢!我的控制器在获取国家方面遇到了问题,但这正是我正在寻找的...再次感谢!如果有人想知道,我最终选择了生成JSON的第二个解决方案。 - Ian Dallas
这段代码如何处理适当的转义?我在第一个片段中看不到任何“双引号”或'单引号',而如果任何国家或省份包含像'这样的特殊字符,则第二个片段将失败。 - Roland Illig

3

我删除了一条评论,在其中说这个不太有用 - 我意识到如果这里的Java类是合适的,它实际上可能非常有用。通过将其转换为JSON字符串,然后您只需输出该字符串并完成即可。但请注意,JSON是完整的JavaScript对象表示法的受限形式,因此对于某些类型的数据,它可能效果不佳。如果能正常工作,那将非常方便。我的应用程序中始终有一个'pointy:toJSON()'EL函数 :-) - Pointy

1
你的代码主要问题是忘记把“status.index”放在${ }中。
countries[${status.index}] = new Array();

话虽如此,如果这样做的话,那将是一种非常糟糕的方式,因为你最终会在页面中得到 大量 JavaScript 代码。使用 JavaScript 对象表示法创建列表会更好,就像 @John Hartsock 的第二个答案一样。


-1
var javaScriptArray = '${javaListVariable}';
                            
javaScriptArray = someList.replace("[","").replace("]","").split(",").map(function(item {
   return item.trim();
});

回答问题时,请记得在您的代码中附上解释。 - Stephen M Irving

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接