How to associate an AngularJS controller with dynamically added HTML?

For this scenario, I have an HTML page with some AngularJS directives, controllers, etc.

Something like that:

<html> <body> <div ng-controller="myCtrl"> <ul><li ng-repeat="item in items">{{item.name}}</li></ul> </div> <div class="placeholder"> ...new HTML here... </div> </body> </html> 

Please note that there is no ng-app directive on the page. I do not rely on automatic loading, but I use the manual boot method.

 angular.bootstrap(document, ['myApp']); 

First, I create a module that will be loaded into the document. Then, when the dynamically defined list of dependencies loads, I attach some services, controllers, etc. Once everything is ready, I call the bootstrap method.

All this works fine until JavaScript outside AngularJS is added to the DOM in ...new HTML here... New HTML is not processed by AngularJS.

I understand that you need to call $scope.$apply() or $digest() or something to make AngularJS recognize the new HTML. However, in my example, there is no controller around the new HTML code. The incoming HTML may look like this:

  <div ng-controller="myOtherCtrl"> <h2>{{model.title}}</h2> </div> 

In other words, it relies on another controller in the application module.

  • I cannot call the angular.bootstrap method angular.bootstrap because the page is already linked.
  • I cannot call $scope.$apply from inside the controller, because the thing is that the controller code is not called.
  • I see no way to get a link to the controller to reapply or update it.

I read the message Ifeanyi Isitor lazy loading post and the message

+13
javascript angularjs
Dec 18 '13 at 6:59
source share
6 answers

I ran into the same problem, here is what I came up with:

 <div id="mController" ng-controller="mainController"> </div> <div id="ee"> 2nd controller view should be rendred here </div> 

and calling the setCnt () function will insert and compile html, and it will be connected to the second controller:

 var app = angular.module('app', []); function setCnt() { // Injecting the view html var e1 = angular.element(document.getElementById("ee")); e1.html('<div ng-controller="ctl2">my name: {{name}}</div>'); // Compile controller 2 html var mController = angular.element(document.getElementById("mController")); mController.scope().activateView(e1); } app.controller("mainController", function($scope, $compile) { $scope.name = "this is name 1"; $scope.activateView = function(ele) { $compile(ele.contents())($scope); $scope.$apply(); }; }); app.controller("ctl2", function($scope) { $scope.name = "this is name 2"; }); 

here is an example to check this out: http://refork.com/x4bc

hope this helps.

+9
Mar 25 '15 at 21:19
source share

Let's take a small template

  var template = '<div ng-controller = "someController">'; template += '<All html you want to add>'; template += '</div>'; 

Now, if you want to add this template, you need to do the following two things:

1) Create your controller using $controller

2) Compile your template.

 //this creates a new scope var $scope = $rootScope.$new(); //Controller initialize with $scope $controller('someController',{$scope,$scope}); var templateEl = angular.element(template); //Now compile the template with scope $scope $compile(templateEl)($scope); angular.element('body').append(templateEL); 
+2
Apr 20 '15 at 19:26
source share

You might want to use the $compile service. What angular does in the first place.

And also this guide: http://docs.angularjs.org/guide/compiler

+1
Dec 18 '13 at 7:43
source share

I had the same problem. This worked for me: https://docs.angularjs.org/api/ng/function/angular.injector

+1
Sep 17 '14 at 20:45
source share

I think ng-include can help you, it loads a partial page into an element and compiles and processes it like any other part of your web page.

If this element is the main view of your web application, and you want to load different "screens" into it, depending on the URL, ng-view may come in handy.

0
Dec 18 '13 at 7:20
source share

I followed this process and worked for me:

 // Some variables var $controllerElement = angular.element('css-selector-to-the-controller-element'); var $appElement = angular.element('css-selector-to-ng-app-element'); // compiling and applying / digesting the scope. $appElement.injector().invoke(function($compile) { var scope = $controllerElement.scope(); $compile($controllerElement)(scope); scope.$apply(); }); 

Link: Angular.injector

0
Jun 13 '16 at 20:32
source share



All Articles