2012-02-20 63 views
13

我想访问Javascript中的模型属性。我使用下面的代码:如何访问Javascript中的模型属性

model.addAttribute("data", responseDTO); 

我的DTO类:

public class ResponseDTO { 

    private List<ObjectError> errors; 

    private Boolean actionPassed; 

    private String dataRequestName; 

    // and setter getter for all fields 
} 

我尝试使用访问DTO:

var data = "${data}"; 

但它给我responseDTO的字符串表示相反,即[email protected]。我可以用成功访问字段中的DTO里:

var data = "${data.actionPassed}"; 

但是这是不工作的DTO内errors属性,因为它是一个ObjectErrorList。如何在Javascript中获得完整的responseDTO对象?

谢谢!


编辑:

起初我是用jquery.post

$.post('ajax/test.html', function(data) { 
    // Here I was able to retrieve every attribute even list of ObjectError. 
}); 

现在我想删除阿贾克斯,并希望将其转换成非Ajax方法(因为一些不得已的原因) 。所以我正在做一个正常的表单提交,并希望再次加载相同的表单,并尝试在Javascript中加载data模型属性,以便我可以保留其余的代码。
我想知道它是否可以在Javascript中实现,因为它是可行的使用JQuery的文章?


编辑2:

我试过(谢谢你@Grant的建议)

JSONObject jsonObject =JSONObject.fromObject(responseDTO); 
String jsonString = jsonObject.toString(); 
model.addAttribute("data",jsonString);  

,并在Javascript

var data = eval('('+ ${dataJson} +')'); // Getting error on this line 
alert(data.actionPassed); 

但得到错误,没有警报显示
错误:
enter image description here

+0

在某个AJAX调用返回DTO之后,您想要在JSP文件或客户端访问该对象的位置? – Ralph 2012-02-20 13:37:25

+0

在继续之前,停止并考虑:您的模型驻留在**服务器**上,JavaScript发生在**客户端**上。现在,你想完成什么? – pap 2012-02-20 14:35:06

+0

@Ralph:不,我想删除Ajax部分。请检查我的编辑了解更多详情。 – xyz 2012-02-20 15:32:10

回答

14

首先,没有办法直接将Java对象转换为Javascript对象,因为它们没有任何关系。一种是服务器端语言,另一种是客户端语言。

所以要完成这个目标,你必须做一些转换。我认为你有两种选择:

  1. 将ResponseDTO对象转换为JSON字符串并将其传递给jsp,您可以直接获取javascript对象。
  2. 将ResponseDTO对象传递给JSP,并将JavaScript对象填充为您现在正在尝试的内容。

对于选项#1,应该使用库来由Java对象生成JSON字符串。你可以使用这个JSON-lib。 如:

JSONObject jsonObject = JSONObject.fromObject(responseDTO); 
/* 
    jsonStr is something like below, "errors" represents the List<ObjectError> 
    I don't know what's in ObjectError, errorName is just an example property. 
    { 
    "dataRequestName":"request1", 
    "actionPassed":true, 
    "errors":[{"errorName":"error"},{"errorName":"unknown error"}] 
    } 
*/ 
String jsonStr = jsonObject.toString(); 
model.addAttribute("dataJson", jsonStr); 

/*In JSP, get the corresponding javascript object 
by eval the json string directly.*/ 
<script> 
var data = eval('('+'${dataJson}'+')'); 
</script> 

对于选项#2,

//Pass java object as you do now 
model.addAttribute("data",responseDTO); 

//In JSP, include jstl taglib to help accessing List. 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

<script> 
var errorArr = [], errorObj; 
<c:forEach var="error" items="${data.errors}"> 
    errorObj = { errorName: '${error.errorName}' }; 
    errorArr.push(errorObj);         
</c:forEach> 

//Populate the corresponding javascript object. 
var data = { 
    dataRequestName: '${data.dataRequestName}', 
    actionPassed: ${data.actionPassed}, 
    errors: errorArr 
}; 
</script> 

正如你所看到的,选项#2是复杂的,只有有用的,如果在Java对象是简单的,而选项1是更容易和维护。

+0

非常感谢您通过简单易用的方式展示。在选项#1中,我可以使用'data.'来访问所有的属性吗?另请检查我的编辑我已添加更多详细信息。 – xyz 2012-02-20 15:36:22

+0

@Ajinkya是的。你可以像使用java对象一样访问所有的属性。唯一的区别是“错误”表示为一个数组。我不知道我理解你的编辑是否正确。你说你能够通过jquery.post检索每个属性甚至是ObjectError的列表,那么为什么会引发这个问题呢? ajax/test.html中有什么? – 2012-02-21 02:11:20

+0

我能够在Ajax回调中访问它,例如在jquery post中定义的函数中。但现在我想删除Ajax,所以我想在Javascript中访问模型属性。 – xyz 2012-02-21 02:20:03

1

因此,我只是用一个对象列表实现了Grant的第一个选项的类似解决方案,但使用Gson库将对象转换为JSON字符串,然后使用JSON.parse()将其转换为javascript对象:

在服务器上:

List<CustomObject> foo = database.getCustomObjects(); 
model.addAttribute("foo", new Gson().toJson(foo)); 

在页面的javascript:

var customObjectList = JSON.parse('${foo}'); 
console.log(customObjectList); 

注意,当我引用模型对象f, oo,我这样做是一个字符串'$ {foo}'。我相信你会得到你的错误,因为你在字符串之外引用它。所以正确的代码是:

var data = eval('('+ '${dataJson}' +')'); 
+0

你将如何处理$ {foo}中的单引号字符?生成的JavaScript将最终为: 'var customObjectList = JSON.parse('{“foo”:“bar's baz”}');' 这是无效的。 使用'fn:replace'很明显,但也似乎有点黑客。是否还有其他需要处理的特殊字符? – Andrew 2016-06-10 19:00:18