有没有办法在JavaScript代码中“期望”某些Java类的实例?

时间:2015-04-28 07:53:23

标签: java javascript angularjs casting

假设我在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"
    //...
}

非常感谢在此主题中回答/评论/编辑的所有人。

4 个答案:

答案 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等等。

希望这会有所帮助,你会看到它的价值。