在Javascript中覆盖方法

时间:2014-09-16 09:44:35

标签: javascript jquery ajax symfony

我最近开始使用JsFormValidatorBundle来验证我在symfony上的表单。唯一的问题是我需要使用Ajax发送这些表单,不幸的是由于某种原因,JsFormValidatorBundle强制通过重新加载页面来发送表单。

所以现在我试图覆盖看起来像这样的函数:

    function FpJsCustomizeMethods() {

    ...

    this.submitForm = function (event) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var element = item.jsFormValidator;
            if (event) {
                event.preventDefault();
            }
            element.validateRecursively();
            if (FpJsFormValidator.ajax.queue) {
                if (event) {
                    event.preventDefault();
                }
                FpJsFormValidator.ajax.callbacks.push(function () {
                    element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
                    if (element.isValid()) {
                        item.submit();
                    }
                });
            } else {
                element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
                if (element.isValid()) {
                    item.submit();
                }
            }
        });
    };

....
}

如果我删除item.submit()它完美无缺。

那么如何覆盖呢?

full script

4 个答案:

答案 0 :(得分:2)

您只需创建一个新函数并通过其原型扩展父级。

也许这个代码块可以解释你需要做什么。

function Parent() {

    this.a = function() {
        alert("i am here");
    }

    this.submitForm = function() {
        alert("i am wrong one here");
    }

}

function Child () {

    //we need to override function submitForm with right one
    this.submitForm = function() {
        alert("i am right one here");
    }

} 

Child.prototype = new Parent;

var c = new Child();
//other parent methods are still accessible.
c.a();
//method submitForm is overriden with the one we defined
c.submitForm();

在行动here

中查看

答案 1 :(得分:0)

有两种方法可以做到这一点。 据我所知,你要覆盖的函数不是jQuery函数。我保留了两个示例,以便您可以决定哪一个适合您的代码。

如果是JavaScript函数(自定义或原生)

首先,我看到了您正在使用的功能,我发现很难覆盖它的特定部分,因此我再次编写并删除(或注释掉)&# 34;提交电话"然后我重写了这个功能。致电FpJsFormValidator时,以下函数将被称为NewFpJsCustomizeMethods

<script type="text/javascript">
FpJsFormValidator = function() {
    return NewFpJsCustomizeMethods();
}

function NewFpJsCustomizeMethods() {
    this.init = function (options) {
        FpJsFormValidator.each(this, function (item) {
            if (!item.jsFormValidator) {
                item.jsFormValidator = {};
            }
            for (var optName in options) {
                switch (optName) {
                    case 'customEvents':
                        options[optName].apply(item);
                    break;
                    default:
                        item.jsFormValidator[optName] = options[optName];
                    break;
                }
            }
        }, false);
        return this;
    };
    this.validate = function (opts) {
        var isValid = true;
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var method = (opts && true === opts['recursive'])
                ? 'validateRecursively'
                : 'validate';
            var validateUnique = (!opts || false !== opts['findUniqueConstraint']);
            if (validateUnique && item.jsFormValidator.parent) {
                var data = item.jsFormValidator.parent.data;
                if (data['entity'] && data['entity']['constraints']) {
                    for (var i in data['entity']['constraints']) {
                        var constraint = data['entity']['constraints'][i];
                        if (constraint instanceof FpJsFormValidatorBundleFormConstraintUniqueEntity && constraint.fields.indexOf(item.name)) {
                            var owner = item.jsFormValidator.parent;
                            constraint.validate(null, owner);
                        }
                    }
                }
            }
            if (!item.jsFormValidator[method]()) {
                isValid = false;
            }
        });
        return isValid;
    };
    this.showErrors = function (opts) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            item.jsFormValidator.errors[opts['sourceId']] = opts['errors'];
            item.jsFormValidator.showErrors.apply(item, [opts['errors'], opts['sourceId']]);
        });
    };
    this.submitForm = function (event) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var element = item.jsFormValidator;
            if (event) {
                event.preventDefault();
            }
            element.validateRecursively();
            if (FpJsFormValidator.ajax.queue) {
                if (event) {
                    event.preventDefault();
                }
                FpJsFormValidator.ajax.callbacks.push(function () {
                    element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
                    if (element.isValid()) {
                        //item.submit();
                    }
                });
            } else {
                element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
                if (element.isValid()) {
                    //item.submit();
                }
            }
        });
    };
    this.get = function () {
        var elements = [];
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            elements.push(item.jsFormValidator);
        });
        return elements;
    };
    //noinspection JSUnusedGlobalSymbols
    this.addPrototype = function(name) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var prototype = FpJsFormValidator.preparePrototype(
            FpJsFormValidator.cloneObject(item.jsFormValidator.prototype),
                name,
                item.jsFormValidator.id + '_' + name
            );
            item.jsFormValidator.children[name] = FpJsFormValidator.createElement(prototype);
            item.jsFormValidator.children[name].parent = item.jsFormValidator;
        });
    };
    //noinspection JSUnusedGlobalSymbols
    this.delPrototype = function(name) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            delete (item.jsFormValidator.children[name]);
        });
    };
}
</script>

如果它是jQuery函数

首先,我看到了您正在使用的功能,我发现很难覆盖它的特定部分,因此我再次编写并删除(或注释掉)&# 34;提交电话&#34;然后我重写了jQuery函数。致电FpJsFormValidator时,以下函数将被称为NewFpJsCustomizeMethods

以下是代码:

<script type="text/javascript">
(function(){
    // Define overriding method
    jQuery.fn.FpJsFormValidator = NewFpJsCustomizeMethods();
})();

function NewFpJsCustomizeMethods() {
    this.init = function (options) {
        FpJsFormValidator.each(this, function (item) {
            if (!item.jsFormValidator) {
                item.jsFormValidator = {};
            }
            for (var optName in options) {
                switch (optName) {
                    case 'customEvents':
                        options[optName].apply(item);
                    break;
                    default:
                        item.jsFormValidator[optName] = options[optName];
                    break;
                }
            }
        }, false);
        return this;
    };
    this.validate = function (opts) {
        var isValid = true;
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var method = (opts && true === opts['recursive'])
                ? 'validateRecursively'
                : 'validate';
            var validateUnique = (!opts || false !== opts['findUniqueConstraint']);
            if (validateUnique && item.jsFormValidator.parent) {
                var data = item.jsFormValidator.parent.data;
                if (data['entity'] && data['entity']['constraints']) {
                    for (var i in data['entity']['constraints']) {
                        var constraint = data['entity']['constraints'][i];
                        if (constraint instanceof FpJsFormValidatorBundleFormConstraintUniqueEntity && constraint.fields.indexOf(item.name)) {
                            var owner = item.jsFormValidator.parent;
                            constraint.validate(null, owner);
                        }
                    }
                }
            }
            if (!item.jsFormValidator[method]()) {
                isValid = false;
            }
        });
        return isValid;
    };
    this.showErrors = function (opts) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            item.jsFormValidator.errors[opts['sourceId']] = opts['errors'];
            item.jsFormValidator.showErrors.apply(item, [opts['errors'], opts['sourceId']]);
        });
    };
    this.submitForm = function (event) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var element = item.jsFormValidator;
            if (event) {
                event.preventDefault();
            }
            element.validateRecursively();
            if (FpJsFormValidator.ajax.queue) {
                if (event) {
                    event.preventDefault();
                }
                FpJsFormValidator.ajax.callbacks.push(function () {
                    element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
                    if (element.isValid()) {
                        //item.submit();
                    }
                });
            } else {
                element.onValidate.apply(element.domNode, [FpJsFormValidator.getAllErrors(element, {}), event]);
                if (element.isValid()) {
                    //item.submit();
                }
            }
        });
    };
    this.get = function () {
        var elements = [];
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            elements.push(item.jsFormValidator);
        });
        return elements;
    };
    //noinspection JSUnusedGlobalSymbols
    this.addPrototype = function(name) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            var prototype = FpJsFormValidator.preparePrototype(
            FpJsFormValidator.cloneObject(item.jsFormValidator.prototype),
                name,
                item.jsFormValidator.id + '_' + name
            );
            item.jsFormValidator.children[name] = FpJsFormValidator.createElement(prototype);
            item.jsFormValidator.children[name].parent = item.jsFormValidator;
        });
    };
    //noinspection JSUnusedGlobalSymbols
    this.delPrototype = function(name) {
        //noinspection JSCheckFunctionSignatures
        FpJsFormValidator.each(this, function (item) {
            delete (item.jsFormValidator.children[name]);
        });
    };
}
</script>

其次,如果你想要覆盖函数中的一些东西:

<script type="text/javascript">
(function(){
    // Store a reference to the original method.
    var originalMethod = jQuery.fn.FpJsFormValidator;

    // Define overriding method.
    jQuery.fn.FpJsFormValidator = function(){
        // Execute the original method.
        originalMethod.apply( this, arguments );
    }
})();
</script>

注意:

您需要在加载原始函数后编写此代码。

答案 2 :(得分:0)

正如我建议你实际上不想覆盖FpJsFormValidator.customizeMethods.submitForm函数只是为了能够通过Ajax而不是默认提交表单。这样做会导致:

  1. 代码重复,因为您将被迫恢复自己功能中的所有验证部分

  2. 如果您的解决方案的一部分将摆脱item.submit()位,那么您也将丢失任何其他事件,这些事件必须被提交作为副产品。

  3. 我只是为该项上的submit事件创建一个处理程序,它将调用event.preventDefault()并执行Ajax请求。当您使用jQuery标记您的问题时,例如:

    $("#your_fav_form_selector").submit(function (e) {
        e.preventDefault();
        // fetch form data and send it off with $.ajax etc
    });
    

答案 3 :(得分:-1)

您好我用以下代码实现了这个目标:

    FpJsFormValidator.customizeMethods.submitForm = function (event) {
... Override Code in here
};