假设我在Java中有Foo.class:
public class Foo {
public int id;
public String data;
}
我在JavaScript中有Foo“class”:
function Foo(id, data) {
this.id = id;
this.data = data;
}
另外,假设我有Java控制器,它返回Foo.class的实例作为对REST请求的响应。在我的JavaScript(AngularJS)代码中,请求以:
发送$http.get(url + 'bar/get-foo/')
.success(function (response) {
var foo = new Foo(response.id, response.data);
logger.info("SUCCESS: /get-foo");
})
.error(function (error_message) {
logger.error(error_message)
});
它有效。但有没有办法避免将每个属性从响应传递给Foo构造函数(某种期望Foo对象,或将其转换为Foo对象)?
我尝试使用Object.create(Foo, response)
,但我得到TypeError: Property description must be an object: true
当然,总是有可能将JavaScript端Foo构造函数重构为:
function Foo(foo) {
this.id = foo.id;
this.data = foo.data;
}
但是,这需要重构大部分代码库。
感谢您的时间。我很感激!
PS:对于那些想知道为什么我需要这个的人:对于像Foo这样的小类来说这不是问题,但是有些响应是更大类(具有十几个字段)的实例,这些不受我的控制编辑:我接受Chichozell的回答只是因为它需要的工作量最少。 Robin和jonnyknowsbest的答案也有效,(并且适用于纯JavaScript,不像Chichozell的答案,这是AngularJS特有的)。没有试过Laurentiu L.的答案,但看起来它也应该有效。 无论如何这是一个解决方案(不是解决方案):
.success(function (response) {
var foo = new Foo();
angular.extend(foo, response); // angular.merge() for "deep-copy"
//...
}
非常感谢在此主题中回答/评论/编辑的所有人。
答案 0 :(得分:1)
你可以做这样的事情来反对#34; deserialise"您收到的JSON作为对初始化对象的响应:
function JSONToObj(jsondata) {
var json = JSON.parse(jsondata);
var name = null;
for(var i in json) { //Use first property as name
name = i;
break;
}
if (name == null)
return null;
var obj = new window[name]();
for(var i in json[name])
obj[i] = json[name][i];
return obj;
}
这假设构造函数存在于全局范围内,并且响应是JSON格式的:
{
"Foo": {
"id": "the id",
"data": "the data"
}
}
答案 1 :(得分:1)
您还可以执行this jsFiddle之类的操作来实现您描述的结构。 createObject函数couold看起来类似于以下代码片段。
function createObject(response, toCreate){
var newObject = new toCreate();
for(var attr in response){
if(newObject.hasOwnProperty(attr)){
newObject[attr] = response[attr];
}
}
return newObject;
}
你有createObject,它将一个与你的函数属性相同的js对象作为响应参数,一个函数(你想要创建的对象)作为toCreate参数。
查看jsFiddle控制台日志输出,您会发现它有效。
你也可以,如jsFiddle中所见,删除对hasOwnProperty的检查以设置响应的所有属性,无论javascript函数是否定义了它们。
答案 2 :(得分:1)
如果你想让你的Java思考javascript,请尝试使用angular.extend(),这将"复制"对象的属性到另一个
this = angular.extend(this, response)
在foo函数中,或直接在控制器上:
Foo = angular.extend(Foo, response)
答案 3 :(得分:1)
如果你愿意,可以使它非常通用。并且不会有太多的重构,这个解决方案可以减轻你对这两个类的未来变化。
您可以将您的Foo javascript对象更改为Angular JS服务,并将其注入您需要的任何位置。这样您就可以在全球范围内使用您的数据。它比局部变量foo更好。
yourApp.factory('Foo',
function () {
//set a default or just initialize it
var fooObject= {};
return {
getId: function () { return fooObject.id; },
getData: function() { return fooObject.data;},
setId: function(newId){fooObject.id = newId},
setData: function(newData){fooObject.data=newData;},
initializeFromObject : function(response){
for (var prop in response){
fooObject[prop] = response[prop];
}
}
};
}
);
您还可以使用hasAllProperties等方法(通过迭代对象的属性,无论是数组还是对象),使新服务的创建更安全。 ; hasNullValues等等。
希望这会有所帮助,你会看到它的价值。