Ninja Turtle
Ninja Turtle

Reputation: 1353

Angularjs code not work when content is loaded from other page using ajax

I am working with AngularJs and php and i am facing problem when i have to load content from some other page then AngularJs stops working.

Here is some sample code to display my scenario.

main-page.php

<div id="form-section">
    <button id="load_form">Load Form</button>    
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript">
$(document).on("click", "#load_form", function() {
   $.ajax({
       methond: 'GET',
       url: 'load-form.php',
       success: function(resp) {
          $("#form-section").html(resp);
       }
   });
});
</script>

load-form.php

<form ng-app="myApp" ng-controller="myCtrl">
{{ textOne }}
<input type="text" ng-model="textOne">
</form>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
   $scope.textOne = "John"; 
});
</script>

if i put <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> in load-form.php and load it directly in browser then AngularJs works there fine. But when i load it through Ajax in main page then my AngularJs code stops working

Upvotes: 1

Views: 146

Answers (1)

Rakesh Makluri
Rakesh Makluri

Reputation: 647

  • When you set innerHTML, script inside the html won't be executed. You need to use eval() or executeScript() or appendChild() may be other to execute the script. (below used setInnerHtml solution is taken from other answer)
  • You need to bootstrap the angular app when you add it dynamically

main-page.php

<div id="form-section">
    <button id="load_form">Load Form</button>    
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript">


var setInnerHtml = function(elm, html) {
  elm.innerHTML = html;
  var scripts = elm.getElementsByTagName("script");
  // If we don't clone the results then "scripts"
  // will actually update live as we insert the new
  // tags, and we'll get caught in an endless loop
  var scriptsClone = [];
  for (var i = 0; i < scripts.length; i++) {
    scriptsClone.push(scripts[i]);
  }
  for (var i = 0; i < scriptsClone.length; i++) {
    var currentScript = scriptsClone[i];
    var s = document.createElement("script");
    // Copy all the attributes from the original script
    for (var j = 0; j < currentScript.attributes.length; j++) {
      var a = currentScript.attributes[j];
      s.setAttribute(a.name, a.value);
    }
    s.appendChild(document.createTextNode(currentScript.innerHTML));
    currentScript.parentNode.replaceChild(s, currentScript);
  }
}

$(document).on("click", "#load_form", function() {
   $.ajax({
       methond: 'GET',
       url: 'load-form.php',
       success: function(resp) {
          setInnerHtml($("#form-section")[0], resp);
       }
   });
});
</script>

load-form.php

<form ng-app="myApp" ng-controller="myCtrl" id="myApp">
{{ textOne }}
<input type="text" ng-model="textOne">
</form>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
   $scope.textOne = "John"; 
});
setTimeout(function() {
     angular.bootstrap(document.getElementById('myApp'), ['myApp'], 100);
// Closing }); was missing here    
});    
</script>

Upvotes: 1

Related Questions