0

I have a scenario where I need to dynamically load an Angular JS application. I have based the code on this:-

https://stackoverflow.com/a/15252490/1545858

Now, I have code that works really well with angular js 1.1.5, but in 1.2.1, no such luck.

Here is the JS code:-

$("#startMeUp").click(function() {
// Make module Foo
angular.module('Foo', []);
// Make controller Ctrl in module Foo
angular.module('Foo').controller('Ctrl', function($scope) { 
    $scope.data = {};
    $scope.data.name = 'KDawg';
    $scope.destroy = function() {
        $scope.$destroy();
        $('#Ctrl').remove();
    };
    $scope.$on("$destroy", function () {
        console.log("EXTERMINATE");
    });
});
// Load an element that uses controller Ctrl
$('<div ng-controller="Ctrl" id="Ctrl"> ' +
  '<input type="text" ng-model="data.name"></input>' +
  '{{data.name}}' +
  '<button ng-click="destroy()">Destroy Me</button></div>').appendTo('#container');
// Bootstrap with Foo
angular.bootstrap($('#Foo'), ['Foo']);
});

And here is the HTML:-

<button id="startMeUp">Start Me Up!</button>

<div id="Foo">
  <div id="container">

  </div>
</div>

Now, if you start and destroy and start again with angular js 1.1.5, everything works fine, but in angular js 1.2.1 it does not work in on the second start. Any thought on how to make it work in 1.2.1?

Here is the js fiddle:-

http://jsfiddle.net/Y9wj2/

Community
  • 1
  • 1
user1545858
  • 725
  • 4
  • 21
  • 1
    if you bootsrap angular once in page, why do you need to do it again? Destroying one controller scope isn't destroying the module or the binding of module – charlietfl Nov 24 '13 at 13:23

1 Answers1

1

As charlietfl says, you don't need to bootstrap more than once. In fact, using angular.js 1.2.1, the error generated that breaks everything is telling you exactly that:

[ng:btstrpd] App Already Bootstrapped with this Element ''

You should think carefully about whether you really need this controller to be dynamic. If you can just use something like ng-include to load the extra content then you will have a much easier time and no need to worry about compiling the content.

If you find you really do need to take this HTML and load it from outside of angular context then you can use the $compile service. Bootstrap the app once somewhere first, preferably using ng-app and grab the injector.

var injector = angular.bootstrap($('#Foo'), ['Foo']);

or

<div id="Foo" ng-app="Foo"></div>

var injector = $('#Foo').injector();

Now you can insert the HTML however you like and then compile and link it using

injector.invoke(['$compile', '$rootScope', function($compile, $rootScope) {
  $compile(insertedJqLiteNode)($rootScope);
});
Andyrooger
  • 6,748
  • 1
  • 43
  • 44
  • What I was trying to achieve was integration of angular js with an existing page and form. Basically, the form will kick off a plain old submit in cases A,B, and C, but D and E uses angular. So I thought if I destroy or create the controller, that might be the best way. Thinking about it more, I think it might be better if I update/create an object and use angular's event bus to communicate this information to angular. I think I will investigate further and may ask another question if I have issues with that. Thanks. – user1545858 Nov 24 '13 at 20:14