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 }
    });
});

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this is probably the best & easiest solution to avoid it being a hack!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.