2010-07-21 13 views
3

J'ai une page avec deux types de formulaires. J'ai une forme unique de type A en haut, et ensuite j'ai 1 ou plusieurs formes de type B en dessous.Le modèle de module Javascript peut-il être utilisé pour les singletons et aussi pour les objets qui sont instanciés multi-temps?

J'utilise le modèle de module + jQuery pour câbler tous les événements sur mes formes, gérer la validation, les appels ajax, etc.

Est-ce le meilleur moyen/valide pour définir un singleton, selon la formule A, et une classe d'objets réutilisable, comme dans le formulaire B? Ils sont très similaires et je ne sais pas si j'ai besoin d'utiliser objet la propriété prototype, new, ou un modèle différent. Tout semble fonctionner pour moi mais j'ai peur de manquer une erreur clé.

Form A javascript ressemble à ceci:

var MyProject.FormA = (function() { 
    var $_userEntry; 
    var $_domElementId; 

    var validate = function() { 
    if($_userEntry == 0) { 
     alert('Cannot enter 0!'); 
    } 
    } 
    var processUserInput = function() { 
    $_userEntry = jQuery('inputfield', $_domElementId).val(); 
    validate(); 
    } 
    return { 
    initialize: function(domElementId) { 
     $_domElementId = domElementId; 
     jQuery($_domElementId).click(function() { 
     processUserInput(); 
     } 
    } 
    } 

})(); 
jQuery(document).ready(function() { 
    MyProject.FormA.initialize('#form-a'); 
}); 

Form B, qui est initialisé une ou plusieurs fois, est défini comme ceci:

var MyProject.FormB = function() { 
    var $_userEntry; 
    var $_domElement; 

    var validate = function() { 
    if($_userEntry == 0) { 
     alert('Cannot enter 0!'); 
    } 
    } 
    var processUserInput = function() { 
    $_userEntry = jQuery('inputfield', $_domElement).val(); 
    validate(); 
    } 
    return { 
    initialize: function(domElement) { 
     $_domElement = domElement; 
     jQuery($_domElement).click(function() { 
     processUserInput(); 
     } 
    } 
    } 

}; 
jQuery(document).ready(function() { 
    jQuery(".form-b").each(function() { 
    MyProject.FormB().initialize(this); 
    }); 
}); 

Répondre

2

Vos deux modules renvoient explicitement des objets qui interdisent l'utilisation de nouveaux.

L'héritage du prototype n'est pas vraiment compatible avec la méthode qui cache votre réalisation avec ce modèle. Bien sûr, vous pouvez réécrire ceci avec un objet formulaire prototype avec votre méthode de validation définie dessus, mais alors cette méthode serait visible et vous perdriez l'encapsulation. C'est à vous de décider si vous voulez un faible encombrement et une initialisation rapide des prototypes (les méthodes partagées n'existent qu'une seule fois, Instantiation fonctionne à temps constant) ou l'encapsulation du modèle de module qui vient avec une légère pénalité de performance (Multiple méthodes identiques définies, instanciation d'objet ralentie car chaque méthode doit être créée à chaque fois)

Dans ce cas, je suggère que la différence de performance est insignifiante, alors choisissez ce que vous voulez. Personnellement, je dirais qu'il y a trop de duplication entre eux et que je serais enclin à les unifier. Avez-vous vraiment besoin d'A pour être un singleton? Quels sont les dangers d'une instanciation accidentelle à deux reprises? On dirait que c'est peut-être sur-ingénierie pour ce problème. Si vous devez vraiment avoir un singleton, j'envelopperais la classe non-singleton (B) comme ceci:

var getSingleton = function() { 
    var form = MyProject.FormB(); 
    form.initialize("#form-a"); 
    console.log("This is the original function"); 
    getSingleton = function() {  
     console.log("this is the replacement function"); 
     return form; 
    } 
    return form; 
} 
1

Je pense que vous avez juste besoin d'écrire une sorte de jQ plugin:

(function($) { 
    $.fn.formValidator = function() { 
     return $(this).each(function() { 
      var $_domElement = $(this); 
      $_domElement.click(function() { 
       if($('inputfield', $_domElement).val() == 0) { 
        alert('Cannot enter 0!'); 
       } 
      }); 
     }); 
    }; 
})(jQuery); 

Dans ce cas, vous exte Module de méthodes d'élément nd jQ et sera capable de l'utiliser pour n'importe quelle quantité d'éléments à la page (pour la collection d'éléments simples ou multiples). En outre, il sera chainable.

Utilisation:

$('#form-a').formValidator(); 
$('.form-b').formValidator(); 

Ou

$('#form-a, .form-b').formValidator(); 

Ofcourse vous pouvez utiliser un module pour stocker cette fonction:

ProjectModule.formValidator = function(selector) { 
    return $(selector).each(function() { 
     var $_domElement = $(this); 
     $_domElement.click(function() { 
      if ($('inputfield', $_domElement).val() == 0) { 
       alert('Cannot enter 0!'); 
      } 
     }); 
    }); 
}; 

Utilisation:

ProjectModule.formValidator('#form-a, .form-b');