Archiv für den Monat Oktober 2014

JavaScript direkt im Chrome debuggen und editieren (Chrome Workspaces)


Ich muss gestehen bisher habe ich Chrome immer nur zum Debuggen benutzt und den Code dann im Visual Studio entsprechend geändert, gespeichert und dann wieder im Chrome debuggt.

Als Entwickler lernt man immer wieder etwas neues dazu und wie ich feststellen musste kann man im Chrome auch schon seit längerem, für lokale Projekte den JavaScript Code und auch die CSS Dateien direkt im Browser in den Developer Tools nicht nur debuggen sondern auch direkt bearbeiten und speichern, OHNE eine extra Extension für Chrome installieren zu müssen.

Man benötigt am besten die neuste Version von Chrome und öffne einfach eine Seite die man lokal debuggen möchte in Chrome.

1. Öffnen der Developer Tools in Chrome am einfachsten mit der rechten Maustaste über “Element untersuchen” oder mit F12.

2. Dann in den Developer Tools in den Settings unter Workspace den Ordner hinzufügen in dem sich unser Webprojekt befindet, in meinem Fall die MVC Seite. Dann fragt Chrome ob dieser Vollzugriff auf dieses Verzeichnis bekommt, dies bestätigt man entsprechend.

image

image

image

Danach wird der Ordner auch in den Workspaces mit angezeigt.

image

3. Wenn man jetzt die Settings wieder schließt, und in den Developer Tools auf “Sources” geht, sieht man links unter seiner lokalen Seite auch noch den Ordner den man eben zu den Workspaces hinzugefügt hat, bei mir war dies “Gui.Mvc”.

image

Wenn man jetzt bereits in den passenden Ordern für z.B. seine JavaScript Dateien geht, bei mir im Beispiel im “Gui.Mvc” Ordner unter “ScriptsApp” und dort eine Datei ändert, kann man diese auch bereits speichern. Wichtig ist nur das die Dateien die man bearbeiten möchte auch ausgecheckt sind, denn sonst kann Chrome nicht darauf zugreifen.

Was noch nicht geht ist das Debuggen, denn wenn wir hier einen Haltepunkt setzen, dann wird Chrome diesen nicht “erreichen”.

4. Damit auch das Debuggen in unserem Workspace Ordner funktioniert, müssen wir diesen entsprechend auf unsere URL mappen. Für das Mappen suchen wir uns z.B. eine JavaScript Datei in unserem Workspace Ordner heraus und über die rechte Maustaste wählen wir “Map to network resource” aus.

image

Danach erscheint ein Overlay in dem er die Datei anzeigt. Sollte eine Datei mit dem gleichen Namen mehrmals vorkommen, dann hier den richtigen “Pfad” auswählen wo die eben ausgewählte Datei liegt.

image

Nach dem die Zuordnung vorgenommen wurde, ändert sich auf der linken Seite auch die Auflistung und die Anzeige für “localhost4420” verschwindet.

image

Jetzt können wir alle Dateien die wir wollen bearbeiten und problemlos auch Haltepunkte in den JavaScript Dateien setzen.

image

5. Das ganze lässt sich auch sehr einfach wieder Rückgängig machen, in dem man einfach auf eine Datei im gemappten Pfad geht und dort “Remove network mapping” klickt.

image

AngularJS Directive TemplateURLs mit ASP.NET MVC (virtuelle Verzeichnisse)


Wie und wo legt man am besten die HTML Templates für die eigenen AngularJS Direktiven ab? AngularJS bietet hier mehrere Möglichkeiten, zum einen über eine Template URL oder das direkte Definieren von Templates im JavaScript über einen String. Auch beim Angeben der Template URLs gibt es zwei Möglichkeiten wo das Template abgelegt werden kann, entweder legt man es in einem entsprechend definierten Script Tag ab oder man greift wirklich auf eine passende URL zu in der eine HTML Datei abgelegt wurde.

Da ich meine Direktiven aber auch über NuGet verteilen möchte, fällt die Möglichkeit mit dem Script Tag bereits weg. Außerdem erkennt Visual Studio nicht direkt das es sich um HTML Code im Script Tag handelt und es gibt dadurch auch kein IntelliSense und keine Autovervollständigung.

Damit bleibt nur noch die Möglichkeit das Template direkt als String zu hinterlegen oder in einer extra HTML Datei. Da ich aber wie bereits erwähnt nicht auf IntelliSense und Autovervollständigung verzichten möchte bleibt nur die Möglichkeit das Template direkt in einer HTML Datei abzulegen. Was im Prinzip auch kein Problem darstellt, außer man legt seine Anwendung in einem virtuellen Verzeichnis ab und nicht direkt im Webserver “root” Verzeichnis.

Im virtuellen “MvcAngularJs” Verzeichnis http://localhost/MvcAngularJs/Home/TemplateUrl

im root http://localhost/Home/TemplateUrl

Denn sobald man seine Anwendung nicht mehr im root ablegt, ist es mir bisher nicht gelungen einen festen Pfad in der Direktive zu hinterlegen der immer gefunden werden kann. Die folgende Template URL kann daher im virtuellen Verzeichnis nicht mehr aufgelöst werden.

“/ScriptsAngular/directives/HtmlTemplates/PanelTemplate.html”

Denn der Server beginnt im root zu suchen unter:

http://localhost/Home/TemplateUrl/ScriptsAngular/directives/HtmlTemplates/PanelTemplate.html

und nicht unter:

http://localhost/MvcAngularJs/Home/TemplateUrl/ScriptsAngular/directives/HtmlTemplates/PanelTemplate.html

daher muss man am besten mit .NET ermitteln wie die aktuelle “root” URL inkl. virtuellem Verzeichnis lautet.

public static class SiteRoot
{
    public static string GetSiteRoot()
    {
        var cnt = new UrlHelper(HttpContext.Current.Request.RequestContext);
        return string.Format("{0}://{1}{2}", (object)HttpContext.Current.Request.Url.Scheme, 
                                             (object)HttpContext.Current.Request.Url.Authority,
                                             (object)cnt.Content("~"));
    }
}

diese URL stelle ich im im JavaScript unter global zur Verfügung und greife dann entsprechend in all meinen Direktiven darauf zu. Dafür muss natürlich immer der gleiche Variablenname verwendet werden und meist definiere ich diesen direkt in der “_Layout.cshtml”. (p.s. sonst halte ich mich fern von global im Js, aber hier hatte ich bisher keine bessere Idee wie sich dies besser realisieren lässt.)


    var siteRoot = '@SiteRoot.GetSiteRoot()'

Jetzt kann man seine Direktive erstellen und die entsprechende Template URL einfach zusammenbauen.

angular.module("panel.directives", [])
    .directive("panelWithHeader", function () {
        return {
            restrict: 'EAC',
            transclude: true,
            templateUrl: siteRoot + "/ScriptsAngular/directives/HtmlTemplates/PanelTemplate.html",
            scope: {
                panelTitle: '='
            }
        }
    });

Damit ist es jetzt möglich seine eigenen Direktiven inkl. der HTML Templates auch über NuGet zu verteilen und die Webseiten können auch in einem virtuellen Verzeichnis abgelegt werden. Man muss nur darauf achten, das man bei jeder neuen MVC Seite einmalig den “siteRoot” definiert (manuell oder über einen Helper).

image

Wer hier eine elegantere Lösung bieten kann, würde ich mich natürlich über einen Hinweis freuen. Das ganze liegt natürlich wieder bei mir auf Codeplex.