2

I'd like my app to generate the paths to my angular templates instead of hard-coding the string paths to them in my JS files. Currently I have the server creating a JSON object with all the info that I need. Here's how the rendered HTML appears:

<div ng-cloak ng-controller="BaseCtrl" ng-init="templatePaths = {
   "items":[
       {"token":"about","template":"http://localhost:32243/ViewTemplate/about.html"},
       {"token":"contact","template":"http://localhost:32243/ViewTemplate/contact.html"},
       {"token":"home","template":"http://localhost:32243/ViewTemplate/home.html"}
   ],"defaultTemplate":"http://localhost:32243/ViewTemplate/home.html"
 }">

Previously I defined my routes like this, but as I would rather use the server-generated object above instead.

app.config([
    "$routeProvider",
    function ($routeProvider) {
        $routeProvider
          .when("/home", {
            templateUrl: "ViewTemplate/home.html"
        }).when("/contact", {
            templateUrl: "ViewTemplate/contact.html"
        }).when("/about", {
            templateUrl: "ViewTemplate/about.html"
        }).otherwise({
            redirectTo: '/home'
        });
    }
]);

The problem I have is that since all my data about my routes is now on $scope.templatePaths, I do not have access to $scopefrom inside app.config and I cannot find a way to add to the routes from inside the controller.

I did try this method, but it seems that it no longer works.

//Wait until templatePaths is init in the view...
$scope.$watch("templatePaths", () => {
    _.each($scope.templatePaths.items, item => {
        $route.routes[item.token] = { templateUrl: item.template }
    });
});
Community
  • 1
  • 1
Chris Barr
  • 29,851
  • 23
  • 95
  • 135

1 Answers1

2

Instead of rendering angular HTML with ng-init in your template (which binds to $scope), have the server render javascript. Something similar to:

<script>
var MYAPP = MYAPP || {};

MYAPP.templatePaths = {
    items: [
        { token: "about", template: "http://localhost:32243/ViewTemplate/about.html" },
        { token: "contact", template: "http://localhost:32243/ViewTemplate/contact.html" },
        { token: "home", template: "http://localhost:32243/ViewTemplate/home.html" }
    ],
    defaultTemplate: "http://localhost:32243/ViewTemplate/home.html"
};
</script>

This should be rendered before the includes for your app.js file(s).

Then in your app.js file, you can use MYAPP as a constant and inject it into your config (or elsewhere as needed):

//define as constant to be injectable.
app.constant("MYAPP", MYAPP);

app.config([
    "$routeProvider", "MYAPP",
    function ($routeProvider, MYAPP) {
        var templatePaths = MYAPP.templatePaths;
        var items = templatePaths.items;
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            $routeProvider.when("/" + item.token, {
                templateUrl: item.template
            });
        }

        $routeProvider.otherwise({
            redirectTo: templatePaths.defaultTemplate
        });
    }
]);

I have used a similar pattern in my projects to make variables set by the server available within the client code.

Patrick
  • 6,828
  • 3
  • 23
  • 31