Javascript对象事件处理程序范围,最佳实践?

时间:2013-07-22 04:44:03

标签: javascript javascript-events event-handling scope

我目前正在编写一个基本上提供表单提交的Javascript模块。

在写作时,我遇到了似乎是经典范围的问题。

我希望submit()方法进行AJAX调用并使用对象方法来处理调用的成功和失败。由于submit()是一个事件处理程序,this不再设置为flagBox对象。因此,我无法再访问flagBox.showSuccess()flagBox.showFail()

起初,我一直在寻找一种设置对象范围自引用的方法,这样我就可以调用类似self.showSuccess()的内容。

目前,我正在使用jQuery.proxy()来设置处理程序的上下文。

我还考虑过实现pub / sub模式或将方法附加到event.data

我很好奇其他解决方案是什么,以及是否有任何我没有找到的“最佳实践”。

(function( $ ) {

    var FlagBox = function() {};
    FlagBox.prototype = {

        constructor: FlagBox,

        init: function() {
            $('.flag-content-box')
                .on('submit', $.proxy(this.submit, this));
        },

        ...

        showSuccess: function() {
            console.log('success');
        },

        showFail: function() {
            console.log('fail');
        },

        submit: function(event) {
            event.preventDefault();

            var that = this;
                formData = $(event.target).serializeObject();

            $.ajax({
                type:"POST",
                url: '/flag/add.json',
                data: formData,
                success : function(data) {
                    that.showSuccess();
                },
                error : function(jqXHR, textStatus, errorThrown) {
                    showFail();
                }
            });
        }
    };

    var flagBox = new FlagBox();
    flagBox.init();

})(jQuery);

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以将成功/失败方法绑定到您的对象,就像这样。这样,总是会使用对象的上下文调用成功/失败方法。

(function( $ ) {

    var FlagBox = function() {};
    FlagBox.prototype = {

        constructor: FlagBox,

        init: function() {
            $('.flag-content-box')
                .on('submit', $.proxy(this.submit, this));
        },

        ...

        showSuccess: function() {
            console.log('success');
        },

        showFail: function() {
            console.log('fail');
        },

        submit: function(event) {
            event.preventDefault();

            var that = this;
                formData = $(event.target).serializeObject();

            var successFn = (function(obj){
                return function(){
                    return obj.showSuccess.apply(obj, arguments)
                }
            })(this);  

            var failureFn = (function(obj){
                return function(){
                    return obj.showFailure.apply(obj, arguments);
                }
            })(this);  

            $.ajax({
                type:"POST",
                url: '/flag/add.json',
                data: formData,
                success : successFn,
                error : failureFn
            });
        }
    };

    var flagBox = new FlagBox();
    flagBox.init();

})(jQuery);