2010-11-26 11 views
4

Je suis à la recherche des meilleures pratiques sur la façon de créer un "contrôle" réutilisable pour une utilisation sur plusieurs vues MVC 3. Je pourrais faire une méthode d'extension d'aide Html (par programmation ou avec les aides déclaratives dans le rasoir) ou je pourrais créer une vue partielle.Comment encapsuler un "contrôle" réutilisable pour les vues ASP.NET MVC 3 + Razor

L'astuce, dans mon cas, est que je dois faire plus que juste vider du HTML dans l'endroit précis que la vue appelle l'assistant/partial. En plus de mettre du balisage HTML à cet endroit, j'ai aussi besoin d'ajouter du code javascript pour le faire fonctionner. Normalement, je mettrais ce code ailleurs dans la page (par exemple, le bas). Ceci n'est bien sûr pas strictement nécessaire. Notez également que le javascript n'est pas spécifique à l'instance de contrôle. En d'autres termes, il est possible d'écrire javascript qui trouve toutes les instances du balisage HTMl de contrôle sur une page et "l'active" avec les événements appropriés, etc.

J'ai pensé à plusieurs possibilités. Avoir le helper/partial vider le HTML et une balise <script> à l'endroit où elle est appelée. Cela semble être une mauvaise idée car cela signifie que le contrôle ne peut être utilisé qu'une seule fois par page.

  • Avoir deux aides. Un pour sortir le balisage HTML, et un second qui crache le javascript. La seconde ne serait appelée qu'une seule fois et serait appelée du bas de la page pour que le script se retrouve au bon endroit. Si j'avais inventé un second contrôle comme celui-ci, j'aurais 4 aides (2 pour HTML, 2 pour Javascript).
  • Inventez une sorte de ScriptManager que les contrôles peuvent enregistrer avec javascript. Le scriptmanager aurait une sorte d'aide qui serait ajouté au bas des pages et viderait le javascript pour tous les contrôles qui avaient enregistré un extrait de script. L'appel à l'aide de scriptmanager pourrait être dans le _layout.cshtml afin qu'il se produise automatiquement sur n'importe quelle page qui en a besoin. Cela ne ferait rien quand une page n'en aurait pas besoin. Cela ne semble pas très MVC-ish, je suppose.
  • Il suffit d'avoir une aide qui crache le code HTML, puis ajouter le javascript au site.js qui est inclus sur chaque page. Le javascript serait assez intelligent pour ne rien faire s'il ne pouvait pas trouver de balisage pertinent sur la page (le balisage aurait un élément wrapper avec une classe particulière). Il y aurait cependant un surcoût de cette recherche de balisage sur toutes les pages, y compris les pages qui n'ont aucun de ces contrôles.
  • Identique à # 4, mais placez le javascript dans son propre fichier .js et incluez-le uniquement sur les pages qui utilisent le contrôle. Cela est plus efficace pour les pages qui n'utilisent pas le contrôle, mais il s'agit d'un fichier .js supplémentaire et d'une requête HTTP associée pour les pages qui le font. Je penche vers # 4, mais est-ce un problème résolu? Y a-t-il une meilleure 6ème option?

  • +0

    Besoin de précisions. S'agit-il d'un contrôle réutilisable pour une entreprise/un personnel/un projet où vous avez un certain contrôle sur l'environnement ou s'agit-il d'un contrôle lorsque vous essayez d'être un fournisseur et que vous espérez revendre? – jfar

    +0

    Cela ne serait réutilisé que dans le cadre de mon projet et de projets connexes (internes à mon entreprise). Un emballage fabuleux n'est pas requis. Une certaine mesure d'infaillibilité serait un bonus car il y a plusieurs développeurs qui le réutiliseraient. –

    Répondre

    2

    Mon entreprise emploie MvcContrib zones portables pour emballer le code dans une DLL pour les composants réutilisables « »

    Chacun de ces composants peuvent être appelés par une méthode d'extension. Par exemple:

    Html.Components().ShowPoll(); 
    

    Dans chacun de ces composants, il existe un moyen d'enregistrer plusieurs fichiers css/js qui sont des ressources intégrées. Notre site principal va extraire les fichiers de ressources et minify + les combine avant de le servir.

    Le composant enregistrera également tout événement sur la page qui sera appelé pendant l'événement Document.OnReady de JQuery. Cela permet à chacun des composants d'être des mini-sites, une fonctionnalité autonome avec ses propres itinéraires, modèles et vues.

    Sur l'ensemble du site, le même zip JS pour tous les composants sont servis. Un parce que le fichier sera mis en cache, et deux - supprime la complexité de déterminer quels composants sont sur la page et les ressources dont il a besoin. Faites-moi savoir si vous souhaitez plus d'informations concernant cette configuration.

    0

    J'ai géré ce problème avec une page de mise en page comportant une section appelée jsCode.

    @RenderSection("jsCode",false) 
    

    Puis, quand je en ai besoin, je crée dans la page de contenu:

    @section jsCode 
    { 
    <script type="text/JavaScript" src="myJsCode.js"></script> 
    } 
    

    vous pouvez également créer une aide qui recrache les scripts dont vous avez besoin pour une page particulière et résumer de cette façon, comme ceci:

    @helper MyJSFunction(string FunctionName){ 
    
         switch(FunctionName) 
         { 
          case "firstFN": 
         <text> 
        <script type="text/JavaScript"> 
         function SaySomethingSilly() 
         { 
          var sillySaying="We are the knights who say 'ni'!"; 
          alert(sillySaying); 
         } 
         </script> 
         </text> 
    
         break; 
         case "secondFN": 
         <text> 
         <script type="text/JavaScript"> 
           function SaySomethingElse() 
         { var sillySaying="We are looking for a shrubbery..."; 
          alert(sillySaying); 
         } 
         </script> 
         </text> 
        break; 
        } 
        } 
    

    Alors ma page de contenu (en supposant que je veux les deux fonctions) ressemble à ceci:

    @{ 
    Page.Title="Using helpers to create scripts";} 
    @section jsCode 
    { 
    @JSHelpers.MyJSFunction("firstFN") 
    @JSHelpers.MyJSFunction("secondFN") 
    } 
    <p>It works!</p> 
    

    qui a produit la sortie:

    <!DOCTYPE html> 
    
    <html lang="en"> 
        <head> 
         <meta charset="utf-8" /> 
         <title>Using helpers to create scripts</title> 
    
    
    <script type="text/JavaScript"> 
        function SaySomethingSilly() 
        { 
         var sillySaying="We are the knights who say 'ni'!"; 
         alert(sillySaying); 
        } 
        </script> 
    
    
        <script type="text/JavaScript"> 
          function SaySomethingElse() 
        { var sillySaying="We are looking for a shrubbery..."; 
         alert(sillySaying); 
        } 
        </script> 
    
    
    
        </head> 
        <body> 
    
    <p>It works!</p> 
        </body> 
    </html> 
    

    Maintenant, si vous voulez obtenir super-efficace, (bien que d'autres mots viennent à l'esprit), vous pouvez passer la fonction d'un tableau JSON ou un dictionnaire ou même un tableau de chaînes avec les noms des scripts que vous vouliez utiliser, ou le JavaScript à importer, ou autre, et utilisez simplement un seul appel à l'aide. Je pense que les appels séparés sont plus faciles à maintenir, quelle que soit la façon dont vous chargez les valeurs de retour de la fonction d'assistance, car vous pouvez voir en un coup d'œil quels scripts vous utilisez sur une page donnée et éliminer ou ajouter -line change plutôt que de changer un élément d'un tableau.

    Comme toujours, votre kilométrage peut varier, mais j'ai exécuté l'échantillon basé sur ce code dans WebMatrix Beta 2 sans aucun problème.

    Lisa Z. Morgan http://www.lairhaven.com