Pergunta

Eu estou usando jQuery com os validadores plugin. Eu gostaria de substituir o validador "necessária" com um dos meus próprios. Esta é fácil:

jQuery.validator.addMethod("required", function(value, element, param) {
    return myRequired(value, element, param);
}, jQuery.validator.messages.required);

Até agora, tão bom. Isso funciona muito bem. Mas o que eu realmente quer fazer é chamar a minha função em alguns casos, e o validador padrão para o resto. Infelizmente, isto acaba por ser recursiva:

jQuery.validator.addMethod("required", function(value, element, param) {
    // handle comboboxes with empty guids
    if (someTest(element)) {
        return myRequired(value, element, param);
    }
    return jQuery.validator.methods.required(value, element, param);
}, jQuery.validator.messages.required);

Eu olhei para o código-fonte para os validadores, e a implementação padrão de "necessária" é definido como um método anônimo em jQuery.validator.messages.required. Portanto, não há outro (não-anônimo) referência à função que eu possa usar.

Armazenar uma referência para a função externamente antes de chamar addMethod e chamando o validador padrão via essa referência não faz diferença.

O que eu realmente preciso fazer é ser capaz de copiar a função validador padrão exigido por valor em vez de por referência. Mas depois de um pouco de pesquisa, eu não consigo descobrir como fazer isso. É possível?

Se for impossível, então eu posso copiar o código fonte para a função original. Mas isso cria um problema de manutenção, e eu preferiria não fazer isso a menos que não há "melhor maneira".

Foi útil?

Solução

Armazenar uma referência para a função externamente antes de chamar addMethod e chamando o validador padrão via essa referência não faz diferença.

Isso é exatamente o deve funcionar .

jQuery.validator.methods.oldRequired = jQuery.validator.methods.required;

jQuery.validator.addMethod("required", function(value, element, param) {
    // handle comboboxes with empty guids
    if (someTest(element)) {
        return myRequired(value, element, param);
    }
    return jQuery.validator.methods.oldRequired(value, element, param);
}, jQuery.validator.messages.required);

Isso deve funcionar também: (E o problema com this é resolvido)

var oldRequired = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
    // handle comboboxes with empty guids
    if (someTest(element)) {
        return myRequired(value, element, param);
    }
    return oldRequired.call(this, value, element, param);
    // return jQuery.oldRequired.apply(this, arguments);
}, jQuery.validator.messages.required);

Outras dicas

Function.prototype.clone = function() {
    var fct = this;
    var clone = function() {
        return fct.apply(this, arguments);
    };
    clone.prototype = fct.prototype;
    for (property in fct) {
        if (fct.hasOwnProperty(property) && property !== 'prototype') {
            clone[property] = fct[property];
        }
    }
    return clone;
};

A única coisa ruim com isso é que o protótipo não é clonado para que você realmente não pode mudá-lo ... Eu estou trabalhando em uma maneira de clonar qualquer tipo de objetos e eu só tenho RegExp resta a fazer. Então eu provavelmente vou editar amanhã e colocar todo o código (que é tipo de muito tempo e não é otimizado, se você usá-lo apenas para as funções e objetos.

E a comentar outras respostas, usando eval () é totalmente estúpido e é um caminho muito longo e o construtor Function é uma espécie do mesmo. Literrals são muito melhores. E incluindo JQuery apenas para que, além disso, se ele não funcionar corretamente (e eu não acho que ele faz) não é a coisa mais brilhante que você pode fazer.

Aqui está uma resposta atualizada

var newFunc = oldFunc.bind({}); //clones the function with '{}' acting as it's new 'this' parameter

No entanto .bind é um novo recurso de JavaScript não é, contudo, uma solução de Mdn

https://developer.mozilla.org/en/JavaScript/ referência / Global_Objects / Função / bind

Além disso, ele não clonar as funções propriedades adicionais.

Nota: Como @gsnedder apontadas: a declaração bound "este" argumento u fornecido (em branco {} acima). Persistirá para futuras chamadas da função, independentemente do excesso de equitação através da apply () / call () funções.

Isto pode ser usado tanto para a sua vantagem, ou desvantagem, dependendo de como você lida com isso.

Eu acho que você está apenas perdendo um pouco do escopo. Tente isto:

jQuery.validator.methods._required = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
    // handle comboboxes with empty guids
    if (someTest(element)) {
        return myRequired(value, element, param);
    }
    return jQuery.validator.methods._required.call(this, value, element, param);
}, jQuery.validator.messages.required);

(este deve ser apenas um comentário a Can eu copiar / clone uma função em JavaScript? ... infelizmente, com rep <50 só pode postar)

Function.prototype.clone=function(){
    return eval( '('+this.toString()+')' );
}

basta, ou mesmo

Object.prototype.clone=function(){
    return eval( '('+this.toString()+')' );
}

pensamentos sobre a eficiência:

  • eficiência humana é muito mais importante do que desperdiçar humana recursos para otimizar ou melhorar a "vida" de uma máquina
  • computadores e sistemas automatizados são supostamente para reduzir o esforço humano não aumentá-la
  • sobrecarga computacional deve afetar seriamente a palatabilidade de um resultado para consumo humano, por muitas muitas pessoas, para justificar o investimento esforço na otimização de código que muitas vezes se torna mais obscuro, misterioso e tão esotéricos que já não pode ser entendido por um estábulo de programadores após horas de tentar "compreender" a lógica

sobre a clonagem: esta questão pode ser bastante retórica

  • o que significa a "clone" um objeto javascript? especialmente no contexto da teoria função recursiva
    • um tema comum a clonagem racionalizar é que ela isola e "protege" um criador de suas mudanças Doppelganger
    • Se a = new Object(); b = new Object(); são a e b clones? como sobre o = Object; a = new o(); b = new o();
  • é realmente necessário?
  • onde é que a clonagem de parada? são os atributos protótipo para ser isolado também para a mudança de um objeto clonado delas não afeta exemplos não associado com o objeto clonado? em cujo caso clonagem deve percorrer todo o caminho até a cadeia protótipo do construtores primitivas que se teriam de ser de alguma forma clonada e isolada (um truque em um navegador é abrir uma nova janela e preenchê-la novamente com a ressalva de que opener . etc. ainda pode vazar efeitos cruzados)

Se você deseja clonar uma função, tente o seguinte:

Function.prototype.clone=function(){
    return eval('['+this.toString()+']')[0];
}

Parece que não há nenhuma 'maneira melhor'. Eu acho que você pode tentar fazer uma função requerida sob encomenda para seu próprio exemplo:

jQuery.validator.addMethod("customRequired", function(value, element, param) {
  return myRequired(value, element, param);
}, jQuery.validator.messages.required);

Parece que você já tentou de tudo. Desculpas se eu não entendi a pergunta.

Respondendo a post anterior, quando eu preciso compartilhar uma função construtora, mantendo protótipo distinta, eu uso um invólucro em uma nova função:

`

init_from_arg_obj = function () {
    return new Function('init', 'for (var i in init) this[i] = init[i];');
};

constructor_A = init_from_arg_obj();
constructor_A.prototype = {a: 'A'};

constructor_B = init_from_arg_obj();
constructor_B.prototype = {b: 'B'};

`

Eu corro vários testes para verificar que isso não execução lenta em motores de boas JS.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top