【问题标题】:Post a javascript object with prototype发布带有原型的 javascript 对象
【发布时间】:2015-12-01 17:05:36
【问题描述】:

要求:

  • 我会创建一个带有方法和属性的 javascript 对象。
  • 我会发布这个对象。

我的代码:

        var SessionManager = (function (my) {
            function addUrl(urlHistory) {
                if (!urlHistory) throw new TypeError('"urlHistory" is null or not defined');
                if (!(urlHistory instanceof UrlHistory)) throw new TypeError('"urlHistory" is not an "UrlHistory" object');

                $.ajax({
                    url: '/CollateralManagement/Session/AddUrl',
                    type: 'POST',
                    success: function (result) {
                    },
                    data: { __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val(), model: urlHistory }
                });
            }

        my.addUrl = addUrl;

        return my;
        })(SessionManager || {});

        var UrlHistory = function (area, controller, view, params) {
            if (params && !Array.isArray(params)) throw new TypeError('The variable "params" is not null and not an array');

            var me = this;

            me.Area = area;
            me.Controller = controller;
            me.View = view;
            me.Params = Array.isArray(params) ? params : [];
        };

        UrlHistory.prototype.coucou = function () {
            console.log(this);
        };

        UrlHistory.prototype.AddParam = function (key, value) {
            this.Params.push({ "Key": key, "Value": value });

            return this;
        };

        //I run the code with this exemple:
        var uh = new UrlHistory("toto", "tata", "titi");
        uh.AddParam("z", "z").AddParam("a", "a");
        SessionManager.addUrl(uh);

我的对象看起来很棒: UrlHistory {区域:“toto”,控制器:“tata”,视图:“titi”,参数:Array[2]}

但是当我输入 ajax 方法时出现这个错误:

Uncaught TypeError: Cannot read property 'push' of undefined

我尝试了同样的调用ajax,没有添加原型,一切都OK。

运行 ajax 函数时,我的 2 个方法被调用,但“this”是“Window”而不是“UrlHistory”。

问题:

  • 为什么在发帖时会调用方法?
  • 如何发布我的对象?

谢谢

【问题讨论】:

  • 您在创建 SessionManager Prototype 时是否使用了“类”?否则 addUrl 附加到窗口对象。请显示更多代码。
  • 似乎this.Params 未定义。也许this 不是您所期望的?试着调试一下你的代码!
  • TJHeuvel,请读到最后。当我在这里使用我的方法时:“uh.AddParam("z", "z").AddParam("a", "a");" “this”是“UrlHistory”(这是正常的)但是当调用ajax运行时,我的方法再次被调用并且“this”是“Window”并且参数是“undefined”,为什么?

标签: javascript jquery ajax oop


【解决方案1】:

以下代码将调用函数something

var Test = function(){
  this.name="Hello World";
}
Test.prototype.something = function(){
  console.log(".... something has been called",this);
  throw new Error("what is the stack?");
}

jQuery.post("",Object.create(new Test()))

那是因为 jQuery 代码中的following line 会检查您的对象成员是否为函数,如果是,它将调用该函数并使用结果值。

jQuery 使用 jQuery.param 将对象序列化为 http post 或获取参数,因此 jQuery.param(new Test()) 会抛出相同的错误。

您想阻止 jQuery 调用该函数,但我在文档中找不到任何内容来覆盖序列化函数,但您可以在 urlHistory 类型中添加一个函数以转换为数据:

var urlHistory = function(){
  this.name="Hello World";
}
urlHistory.prototype.something = function(){
  console.log(".... something has been called",this);
  throw new Error("what is the stack?");
};
urlHistory.prototype.toData =  function(){
    var ret = {};
    //this works in your example but if nested objects have functions
    //  it may still fail
    for ( prefix in this ) {
        if(typeof this[ prefix ] !== "function" ){
          ret[ prefix ] = this[ prefix ];
        }
    }
    return ret;
}

console.log("..... working:",jQuery.param((new urlHistory()).toData()))

在您的情况下,您可以将 toData 添加到 urlHistory,然后在 ajax 调用中执行:model: urlHistory.getData()

【讨论】:

  • 谢谢,很遗憾你的回答是我所想的......但我希望存在更好的解决方案。
【解决方案2】:

我知道这个问题很老,但这对我有很大帮助,希望对其他人有所帮助。

当通过 ajax 发送数据时,我只是先对其进行编码和解码

var object //this is your object with a prototype
var send_data = $.parseJSON(JSON.stringify(object)); //this encodes and decodes 

$.ajax({
     url: '/someurl',
     type: 'post',
     data: send_data
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多