0

In AngularJS I'm trying to manually load a template that uses a predefined controller.

I call a WebApi to get a list of available templates. When this list is received I should load each template onto the page. Each template also uses an AngularJS controller so the connection between the template and the preloaded controller must work.

After some googling I ended up on this previous (and somewhat old) question: AngularJS Manually Render Controller and Template

It seems to do exactly what I want, but it has a directive that uses more parameters than I need. Also, I don't have directives for my templates. I just can't wrap my head around how to get it to do what I want.

How can I get ExampleTemplateToLoad.html to be loaded by code, inserted into div#LoadedTemplates while functioning like a normal template using a controller?

main.js

var myApp = angular.module('myApp', [.....]);
myApp.config(function($routeProvider) {
    $routeProvider.when('/', { templateUrl : '/mainTemplate.html' });
});

myApp.controller('mainController', function ($scope, $http) {
    $http.get('/api/getListOfTemplateScripts').success(function (data) {
        // This returns a list of scripts that should be loaded
        // Scripts are loaded using https://github.com/ded/script.js
        // These scripts show up in "Sources" in Chrome Developer Tools,
        // and any syntax errors in these scripts are also displayed in
        // the console, so the script is definitely loaded
        angular.forEach(data, function (scriptFile, key) {
            $script(scriptFile, function() {
                console.log(scriptFile + " loaded");
            });
        });
    })
    .then(function() {
        $http.get('/api/getListOfTemplate').success(function (data) {
            // This returns a list that includes ExampleTemplateToLoad.html
            // The template should then be loaded into div#LoadedTemplates
            angular.forEach(data, function (templateFile, key) {
                // This is logged *after* "scriptToLoad loaded" in the console
                console.log('Loading template ' + templateFile);
            });
        });
    });
});

mainTemplate.html

<div ng-controller="mainController">
    <div id="LoadedTemplates"></div>
</div>

ExampleTemplateToLoad.html

<div ng-controller="loadedTemplateController">
    <!-- Do whatever the template needs to do, using variables defined
         in $scope as it would normally do -->
</div>

ExampleTemplateControllerToLoad.js

myApp.controller('loadedTemplateController', function ($scope, $http) {
});

1 Answer 1

1

Not sure if ur supposed to be modifying DOM from a controller but I'd try binding your "LoadedTemplates" to a variable (using ng-model) and in the controller, once you get the dynamic template back from the $http.get, get a reference to the div, i.e.

var target = $document[0].getElementById('LoadedTemplates')

and then do something along the lines of:

element.append(htmlReturnedByService);
$compile( element.contents() )( $scope );

Haven't tested, but maybe this helps :D

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

7 Comments

First error in console is scope is not defined. If I try to replace scope with $scope I get Argument 'loadedTemplateController' is not a function, got undefined. This is due to the lazy loading of the template's script file. If I put the controller in main.js it works. I'm updating the code above to also show lazy loading of scripts.
Though your browser might be loading the script, the controller has to be registered in your angular app. Try using $controllerProvider.register instead of $script?
How do I use $controllerProvider.register when all I have is a link to a JS file?
Never mind to the last comment. If I, in myApp.config save a reference to $controllerProvider.register, I can use that reference in my lazy loaded JS file instead of myApp.controller, and now it works. Now to get this to work in a directive, as you are correct in saying the DOM shouldn't be modified from a controller.
@GTHvidsten well, glad I'm helping a bit :)
|

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.