Search code examples
htmlangularjsasp.net-mvcrootvirtual-directory

Referencing resources in a global way either from a virtual directory or the web root?


Let's say I have an MVC/WebAPI/AngularJS site that I'm running locally, e.g. ;

localhost/Test/

which I then want to move to

www.test.com

While local, I have a lot of references to various directories (jsfiles, etc) of the following format (in either JS or HTML files)

app.directive('rpdbSpinner', function() {
    return {
        restrict: 'E',
        **templateUrl: '/Test/templates/directives/spinner.html',**
        scope: {
            isLoading:'='
        }
    }
})

when updating/web publishing, I'd have to change everything to:

app.directive('rpdbSpinner', function() {
    return {
        restrict: 'E',
        **templateUrl: '/templates/directives/spinner.html',**
        scope: {
            isLoading:'='
        }
    }
})

I can do this manually (which is what I've been doing),but the larger the project grows, the harder it becomes. I could, of course, only change it once and then excluded the files during publishing phase (web.config/rest), but it still feels like I am going about it the wrong way. Using "~/" wouldn't work on plain HTML/JS files as far as I'm aware, and this I can't really use it...

Any suggestions to map to paths globally regardless of whether in a Virtual Directory or the root of a project?

Thanks :)


Solution

  • If you simply care about getting the root/base url of the site so you can append that to get the other url you are after, you may simply use / as the first character of your url.

    var getUsersUrl =  "/api/users";
    

    Here is an alternate approach if you want more than just the app root (Ex : Specific urls( built using mvc helper methods such as Url.RouteUrl etc)

    You should not hard code your app base path like that. You may use the Url.Content or Url.RouteUrl helper methods in your razor view to generate the url to the app base. It will take care of correctly building the url regardless of your current page/path.Once you get this value, assign it to a javascript variable and use that in your other js code to build your other urls. Always make sure to use javascript namespacing when doing so to avoid possible issues with global javascript variables.

    So in your razor view (Layout file or specific view), you may do this.

    <script>
        var myApp = myApp || {};
        myApp.Urls = myApp.Urls || {};
        myApp.Urls.baseUrl = '@Url.Content("~")';    
        myApp.Urls.userListUrl = '@Url.Action("Index","User")';       
    </script>
    <script src="~/Scripts/NonAngularJavaScript.js"></script>
    <script src="~/Scripts/AngularControllerForPage.js"></script>
    <script>
        var a = angular.module("app").value("appSettings", myApp);
    </script>
    

    In your angular controller, you can access it like,

    var app = angular.module("app", []);
    var ctrl = function (appSettings) {
    
        var vm = this;
        console.log(appSettings.Urls.userListUrl);
    
        vm.baseUrl = appSettings.Urls.baseUrl;
        //build other urls using the base url now
        var getUsersUrl = vm.baseUrl + "api/users";
        console.log(getUsersUrl);
    
    };
    app.controller("ctrl", ctrl)
    

    You can also access this in your data services, directives etc.

    In your non angular java script files.

    // With the base url, you may safely add the remaining url route.
    var urlToJobIndex2= myApp.Urls.baseUrl+"jobs/GetIndex";