wake-up-neo.com

Ist es in Ordnung, JavaScript in Teilansichten zu setzen

Ich arbeite an einer Web-App, bei der die Hauptseite zwei Teile enthält: den konstanten Block, der immer sichtbar ist, und den Infoblock, der aus einer der drei Teilansichten besteht. Jede der Teilansichten erscheint als Ergebnis der Anforderung AJAX und wird nur einmal geladen (danach wird das Fensterwechsel von jquery bereitgestellt). Es funktioniert gut, aber ich hatte ein Problem.

Der HTML-Code von Teilansichten enthält js-Funktionen, die sowohl im Konstantenblock als auch im Infoblock verwendet werden. Wenn die Seite geladen ist, können sich diese Funktionen gegenseitig "sehen" und funktionieren, aber die Neueinteilung kann keine Funktionsdeklarationen finden und mich warnen. Ich kann das Problem nicht lösen, indem ich sie aufgrund der Rasiermesser-Syntax, die in ihrem Code enthalten ist, in eine externe JS-Datei überträgt.

Was kann ich damit machen?

Vielen Dank.

Update:

Schließlich habe ich beschlossen, das Problem zu lösen, das meinen js-Code von Ansichten unterscheidet. Die neue Frage war also, wie man Rasiermesser-Syntax in js-Dateien einbinden kann oder was die akzeptable Alternative ist. Die beliebtesten Lösungen, die ich gefunden habe, verwenden globale Variablen, Datenattribute und die, die ich mehr mag, die RazorJS-Bibliothek von John Katsiotis.

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

Ich hoffe, es wird stabil funktionieren und Resharper glücklich machen. 

Prost!

Update:

Nach drei Jahren erinnerte ich mich an diese Frage und beschloss, sie nach meinen Erfahrungen zu aktualisieren. Tatsächlich würde ich jetzt lieber keine zusätzlichen Bibliotheken dafür empfehlen. Vor allem, wenn Sie nicht das einzige Mitglied im Projektteam sind… Es ist viel besser, wenn Sie in allen Ihren Bibliotheken sichergestellt sind. Sie werden vom Ersteller und der Community unterstützt und können problemlos in Ihre IDE integriert werden (wenn Sie spezielle verwenden.) Syntax zum Beispiel). Auch alle Jungs aus Ihrem Team sollten wissen, wie es funktioniert. Nun würde ich vorschlagen, die nächsten Dinge zu tun:

  1. Halten Sie alle JS in separaten Dateien. Isolieren Sie es so viel wie möglich. Stellen Sie die externe API dafür bereit. 
  2. Rufen Sie die API-Funktionen von Ihren Ansichten aus auf. 
  3. Übergeben Sie alle von Razor generierten URLs, Textnachrichten und Konstanten als Ressourcenparameter.

Zum Beispiel:

jS-Datei:

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

Aussicht:

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

Wenn Resharper Sie warnt, ist es keine große Sache ^ _ ^

Aber wenn ich du wäre, würde ich JavaScript nicht in die Teilansicht setzen

Da die Teilansicht oft auf einer Seite eingefügt werden konnte, treten Probleme mit Ihren JavaScripts auf.

Und wenn Sie das JavaScript nicht in die JS-Datei trennen können, erstellen Sie einfach erstellen Sie eine andere PartialView, fügen Sie diese Skripts hinzu und rendern Sie sie auf Ihrer Hauptseite.

30
Wahid Bitar

Wenn Sie Teilansichten schreiben möchten, die gekapselte "Widgets" sind, die nur funktionieren, wenn Sie sie in eine Seite einbinden, ist das Einbetten eines Skriptblocks in die Teilansicht eine saubere Möglichkeit, das Markup und das Initialisierungsskript in einer Teilansicht zusammenzufassen . Zum Beispiel könnte ich eine Teilansicht namens "_EventList" haben, die ich auf meiner Website verwende. Wenn ich an zwei Stellen auf meiner Masterseite platziere, sollte es funktionieren und ich ziehe es vor, keine Logik in meine Masterseite zu schreiben, um das Widget zu initialisieren.

Wenn Sie es niemals mehr als einmal auf einer Seite verwenden, ist es einfach. Wenn Sie möchten, wickeln Sie das Skript so ein, dass es nicht zweimal ausgeführt wird. Siehe unten. Aus Gründen der Stapelüberlauf-Snippets simuliere ich sie, indem ich die Teilansicht zweimal im Code-Snippet wiederhole, um eine Teilansicht zweimal in einer Masterseite darzustellen.

Meine Masterseite könnte folgendermaßen aussehen:

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

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

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

Beispiel:

<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

Ich stimme mit Wahid überein, dass Sie JavaScript in Ansichten nicht oder nur teilweise einfügen sollten. Ich habe genug Code gesehen, der dies tut, um zu wissen, dass es nur zu keinem Guten führt.

Ich würde auch sagen, dass Sie in der Lage sein sollten, die in der Razor-Syntax gekapselte Logik in das JavaScript zu übertragen. Sie müssen nur die von Ihrer Logik benötigten Informationen an Ihr JavaScript übergeben.

Ich schätze nur aus Erfahrung mit diesem nächsten Kommentar, aber Sie sollten JavaScript so gestalten, wie Sie die Struktur Ihres C # - oder VB.NET-Codes entwerfen würden. Auf diese Weise sollte die Logik, für die Sie Razor verwenden, Bestandteil Ihres JavaScript sein.

Auf diese Weise lässt sich Ihr JavaScript einfacher pflegen und ich gehe davon aus, dass Resharper auch glücklicher sein sollte.

3
eaglestorm

Ich mache das und finde es sehr bequem. Es funktioniert gut, um teilweise Javascript-Snippets mit der Verfügbarkeit von ViewBag, HttpContext usw. dynamisch zu laden. 

Es ergibt sich etwas, das sich anfühlt, T4-Vorlagen zu verwenden. 

Sie können sogar Javascript-Überprüfung, Intellisense usw. erhalten, wenn Sie solche Phantom-Skript-Tags hinzufügen.

@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

Für zukünftige Zuschauer dieser Frage ist hier meine Erfahrung. Ich dachte, es wäre eine gute Idee, die Skripts zu behalten, die nur von der partiellen in der partiellen Organisation verwendet werden. 

Das Problem, das ich hatte, war während des Debuggens. Manchmal hatte ich Schwierigkeiten, meine Haltepunkte zu erreichen, und ich konnte ein Problem nicht beheben, wenn ich das Skript nicht in die übergeordnete Ansicht verschoben habe. Wahrscheinlich, weil die Funktion mehr als einmal gedruckt wurde. Ich hatte gehofft, Abschnitte würden das besser lösen und organisieren, aber Abschnitte werden in Teilansichten nicht unterstützt (zumindest nicht in MVC 4).

Meine Antwort wäre also aus Gründen der Wartung und des Debugging, dass keine Skripte nicht in Teilansichten eingefügt werden sollten. 

0
eaglei22