web-dev-qa-db-fra.com

Est-il possible de mettre JavaScript dans des vues partielles

Je travaille sur l’application Web où la page principale contient deux parties: le bloc constant qui est toujours visible et le bloc info constitué de l’une des trois vues partielles. Chacune des vues partielles apparaît à la suite de la demande AJAX et est chargée une seule fois (après que jstery change de fenêtre). Cela fonctionne bien mais je suis confronté à un problème.

Le code html des vues partielles contient des fonctions js utilisées dans le bloc constant et dans le bloc info également. Lorsque la page est chargée, ces fonctions peuvent se "voir" les unes des autres et cela fonctionne, mais le resharper ne peut pas trouver les déclarations de fonction et m'en avertir. Je ne peux pas résoudre le problème en les transférant dans un fichier js externe à cause de la syntaxe de rasoir qui se trouve dans leur code.

Que puis-je faire avec ça?

Merci.

Mettre à jour:

Enfin, j’ai décidé de résoudre le problème qui sépare mon code js des vues. La nouvelle question était donc de savoir comment inclure la syntaxe de rasoir dans les fichiers js ou quelle est la solution de remplacement acceptable. Les solutions les plus courantes que j’ai trouvées utilisent des variables globales, des attributs de données et celle que j’aime plus, la bibliothèque RazorJS de John Katsiotis.

http://djsolid.net/blog/razorjs---write-razor-inside-your-javascript-files

J'espère que cela va fonctionner de manière stable et rendre Resharper heureux. 

À votre santé!

Mettre à jour:

Après 3 ans, j'ai rappelé cette question et décidé de la mettre à jour en fonction de mon expérience. En fait, je préférerais ne pas utiliser de bibliothèques supplémentaires pour cela. Surtout si vous n’êtes pas le seul membre de l’équipe de projet… C’est beaucoup mieux si vous êtes assuré dans toutes vos bibliothèques, elles sont supportées par le créateur et la communauté et peuvent facilement être intégrées dans votre IDE syntaxe par exemple). Tous les membres de votre équipe doivent également savoir comment cela fonctionne. Alors maintenant, je suggère de faire les choses suivantes:

  1. Tenir tous les JS dans des fichiers séparés. Isolez-le autant que vous le pouvez . Fournissez l'API externe pour cela. 
  2. Appelez les fonctions de l'API depuis vos vues. 
  3. Transmettez toutes les URL, messages texte et constantes générés par Razor en tant que paramètre de ressource.

Par exemple:

fichier js:

$.api.someInitFunction = function(resources){ ... }

Vue:

<script>
    $.api.someInitFunction({
        urls: { myAction: '@Url.Action("MyAction", "MyController")' },
        messages: { error: '@errorMessage' },
        consts: { myConst: @myIntConst }
    });
</script>
54
Tomy

Si Resharper vous prévient, ce n'est pas grave ^ _ ^

_ {Mais si j'étais vous je ne mettrais pas du tout JavaScript dans la vue partielle}. 

Étant donné que la vue partielle peut être insérée plusieurs fois dans une page, vous rencontrez un problème avec vos scripts Java.

Et dans votre cas, si vous ne parveniez pas à séparer le fichier JavaScript vers JS, vous n'avez alors que créez un autre PartialView, insérez-y ces scripts et affichez-le dans votre page principale.

30
Wahid Bitar

Si vous souhaitez écrire des vues partielles encapsulées dans des "widgets" fonctionnant une fois que vous les avez incluses dans une page, l'intégration d'un bloc de script à l'intérieur de la vue partielle constitue un moyen simple de regrouper le balisage et le script d'initialisation dans une vue partielle. . Par exemple, je pourrais avoir une vue partielle nommée "_EventList" que j'utilise sur tout mon site. Si je place à deux endroits sur ma page maître, cela devrait fonctionner et je préfère ne pas avoir à écrire de logique dans ma page maître pour initialiser le widget.

Si vous ne l'utilisez jamais plus d'une fois dans une page, c'est simple. Mais si vous le pouvez, enroulez le script pour qu'il ne s'exécute pas deux fois. Voir ci-dessous. Par souci d'extraits de Stack Overflow, je le simule en répétant la vue partielle deux fois dans l'extrait de code pour représenter une vue partielle deux fois dans une page maître.

Ma page maître pourrait ressembler à ceci:

<div id="left-nav">
   @Html.Partial("_EventList")           
</div>

<div id="body">
</div>

<div id="right-nav">
   @Html.Partial("_EventList")
</div>

Exemple:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Self-contained partial view containing widget -->

<div id="widgetDiv" class="panel panel-default">

    <div class="panel-heading">Event Dates</div>
    <div class="panel panel-group">
       <ul class="widget">
         <!-- These will load dynamically -->
       </ul>
    </div>

    <script>
        $(document).ready(function() {

            // Run this once only in case widget is on page more than once
            if(typeof $widget == 'undefined') {
                $widget = $("ul.widget"); // could be more than one
                // mock data to simulate an ajax call
                var data = [
                   {Description: "March", StartDate: "03/01/2015"},
                   {Description: "April", StartDate: "04/01/2015"},
                   {Description: "May", StartDate: "05/01/2015"}
                ];

                $.each($widget, function(w, widget) {
                    // might be an $.ajax call
                    $.each(data, function(i, row) {
                        $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>");
                    });
                });
            }
        });
    </script>
</div>
<!-- End of widget / partial view -->



<!-- Second copy of above for sake of example snippet -->
<!-- No need to read further -->









<!-- Self-contained partial view containing widget -->

<div id="widgetDiv" class="panel panel-default">

    <div class="panel-heading">Event Dates</div>
    <div class="panel panel-group">
       <ul class="tinylist nav nav-sidebar widget">
         <!-- These will load dynamically -->
       </ul>
    </div>

    <script>
        $(document).ready(function() {

            // Run this once only in case widget is on page more than once
            if(typeof $widget == 'undefined') {
                $widget = $("ul.widget"); // could be more than one
                // mock data to simulate an ajax call
                var data = [
                   {Description: "March", StartDate: "03/01/2015"},
                   {Description: "April", StartDate: "04/01/2015"},
                   {Description: "May", StartDate: "05/01/2015"}
                ];

                $.each($widget, function(w, widget) {
                    // might be an $.ajax call
                    $.each(data, function(i, row) {
                        $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>");
                    });
                });
            }
        });
    </script>
</div>
<!-- End of widget / partial view -->

6
codenheim

Je suis d'accord avec Wahid pour dire que vous ne devriez pas mettre JavaScript dans des vues partielles ou autres. J'ai vu assez de code qui fait cela pour savoir que cela ne mène à rien de bon.

Je dirais également que vous devriez pouvoir transférer la logique encapsulée dans la syntaxe Razor dans le code JavaScript, il vous suffit de transmettre à votre code JavaScript les informations nécessaires à votre logique.

Je devine juste de l'expérience avec ce commentaire suivant mais vous devriez concevoir le JavaScript de la même manière que vous concevriez la structure de votre code C # ou VB.NET. Ainsi, la logique que vous utilisez pour Razor devrait faire partie de votre JavaScript.

De cette façon, votre JavaScript sera plus facile à gérer et je suppose que Resharper devrait également être plus heureux.

3
eaglestorm

Je le fais et le trouve très pratique. Cela fonctionne bien pour charger dynamiquement des extraits de code javascript partiels avec la disponibilité de ViewBag, HttpContext, etc. 

Il en résulte quelque chose qui ressemble à l'utilisation de modèles T4. 

Vous pouvez même obtenir une validation javascript, intellisense, etc. si vous ajoutez des balises de script fantômes comme celle-ci.

@using System.Configuration
@if (false)
{
    @:<script type="text/javascript">
}    
        $scope.clickCartItem = function(cartItem) {
            console.log(cartItem);
            window.location.href [email protected]("('" + ConfigurationManager.AppSettings["baseUrl"] + "/Checkout/' + cartItem.ItemId)");
        };
        dataAccess.getCart(
        function (response) {
            //...
        },
        function (response) {
            //...
        }
        );

@if (false)
{
    @:</script>
}
2
Bon

Pour les futurs téléspectateurs de cette question, voici mon expérience. Je pensais que ce serait une bonne idée de garder les scripts qui n'étaient utilisés que par le partiel dans le partiel pour l'organisation. 

Le problème que j’avais était lors du débogage, j’avais parfois du mal à atteindre mes points d’arrêt et je ne pouvais pas résoudre un problème si je ne déplaçais pas le script dans la vue parent. Probablement dû à l'impression de la fonction plus d'une fois. J'espérais que les sections résoudraient et organiseraient mieux cela, mais les sections ne sont pas prises en charge dans les vues partielles (du moins pas dans MVC 4).

Donc, ma réponse serait pour des raisons de maintenance et de débogage, aucun script ne devrait être placé dans des vues partielles. 

0
eaglei22