在javascript对象中执行回调函数

时间:2013-12-19 16:45:50

标签: javascript callback scope javascript-objects

我想在对象中执行回调函数。我不知道我这样做的方式是否有问题。

我已经搜索了一个解决方案,也在stackoverflow上搜索但找不到类似于我编码的方式。

PHPGateway.js

var PHPGateway = {

    opt_friendlyURL: true,
    opt_folder: 'ajax/',

    callback_function: null,

    useFriendlyURL: function (bool) {
        this.opt_friendlyURL = bool;
    },

    setFolder: function (folder) {
        this.opt_folder = folder;
    },

    send: function (service, method, data, callback) {
        var url,
            json_data = {};
        if (this.opt_friendlyURL) {
            url = this.opt_folder + service + '/' + method;
        } else {
            url = this.opt_folder + 'gateway.php?c=' + service + '&m=' + method;
        }
        if (data != undefined) {
            json_data = JSON.stringify(data);
        }
        this.callback_function = (callback == undefined) ? null : callback;
        $.ajax({
            method: 'POST',
            url: url,
            data: {data: json_data},
            success: this.ajax_success,
            error: this.ajax_error
        });
    },

    ajax_success: function (returned_object) {
        if (this.callback_function != null) {
            this.callback_function(returned_object.error, returned_object.data);
        }
    },

    ajax_error: function () {
        this.callback_function.call(false, {});
    }

};

然后在加载PHPGateway.js的HTML文件中,我有以下代码:

<script>
    function submit_handler(event) {
        event.preventDefault();
        form_submit();
    }
    function form_callback(error, data) {
        if(error == null) {
            alert(data.text);
        }
    }
    function form_submit() {
        var data = {
            status: $('#inStatus').val(),
            amount: $('#inAmount').val(),
            id: $('#inBudgetID'). val()
        }
        PHPGateway.send('budget', 'status', data, form_callback);
    }
    $('form').one('submit', submit_handler);
</script>

我在this.callback_function(returned_object.error, returned_object.data);收到错误,错误是未捕获TypeError:对象#没有方法'callback_function'

  1. 我做错了什么?
  2. 这是最好的方法吗?
  3. 谢谢!

    根据minitech的回答,我已经像这样更新了PHPGateway.js。我省略了未更新的部分。

    var PHPGateway = {
    
        // Omitted code
    
        send: function (service, method, data, callback) {
            var url,
                json_data = {},
                that = this;
            if (this.opt_friendlyURL) {
                url = this.opt_folder + service + '/' + method;
            } else {
                url = this.opt_folder + 'gateway.php?c=' + service + '&m=' + method;
            }
            if (data != undefined) {
                json_data = JSON.stringify(data);
            }
            this.callback_function = (callback == undefined) ? null : callback;
            $.ajax({
                method: 'POST',
                url: url,
                data: {data: json_data},
                success: function(data, textStatus, jqXHR) {
                    that.ajax_success(data, textStatus, jqXHR);
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    that.ajax_error(jqXHR, textStatus, errorThrown);
                }
            });
        },
    
        ajax_success: function (data, textStatus, jqXHR) {
            if (this.callback_function != null) {
                this.callback_function(true, data.data);
            }
        },
    
        ajax_error: function (jqXHR, textStatus, errorThrown) {
            this.callback_function.call(false, {});
        }
    
    };
    

    现在有效!!!

2 个答案:

答案 0 :(得分:2)

在您对$ .ajax的调用中,您需要添加context选项:

$.ajax({
    method: 'POST',
    url: url,
    data: {data: json_data},
    context: this,
    success: this.ajax_success,
    error: this.ajax_error
});

您的Ajax成功和错误处理程序中的this变量未指向您认为它们的对象。 $ .ajax()的context选项设置Ajax回调中指向的对象this

答案 1 :(得分:1)

这是你的问题:

$.ajax({
    method: 'POST',
    url: url,
    data: {data: json_data},
    success: this.ajax_success,
    error: this.ajax_error
});

当您将successerror设置为this上的方法时,他们不会保留this。调用JavaScript函数时,它会绑定this

someFunction(); // this is undefined or the global object, depending on strict
someObject.someFunction(); // this is someObject

.call对象的内置.apply.bindFunction可帮助您覆盖此内容。

在你的情况下,我认为jQuery将this绑定到Ajax对象 - 这是一个不使用jQuery并始终使用严格模式的好理由。

如果您可以保证或支持ES5支持,bind是一个简单的解决方法:

$.ajax({
    method: 'POST',
    url: url,
    data: {data: json_data},
    success: this.ajax_success.bind(this),
    error: this.ajax_error.bind(this)
});

如果你不能,那等同于:

var that = this;

$.ajax({
    method: 'POST',
    url: url,
    data: {data: json_data},
    success: function() {
        that.ajax_success.apply(that, arguments);
    },
    error: function() {
        that.ajax_error.apply(that, arguments);
    }
});

现在,给你一个提示:不要命名空间,如果你这样做,不要使用thisthis非常适合要构造的对象。如果您真的需要,那么看起来更合适的是这样的事情:

var PHPGateway = (function() {
    var callbackFunction;
    var options = {
        friendlyURL: true,
        …
    };
    …

    function send(service, method, data, callback) {
        …
    }
    …

    return { send: send };
})();