dom - Compiling dynamic HTML strings from database -


the situation

nested within our angular app directive called page, backed controller, contains div ng-bind-html-unsafe attribute. assigned $scope var called 'pagecontent'. var gets assigned dynamically generated html database. when user flips next page, called db made, , pagecontent var set new html, gets rendered onscreen through ng-bind-html-unsafe. here's code:

page directive

angular.module('myapp.directives')     .directive('mypage', function ($compile) {          return {             templateurl: 'page.html',             restrict: 'e',             compile: function compile(element, attrs, transclude) {                 // nothing                 return {                     pre: function prelink(scope, element, attrs, controller) {                         // nothing                     },                     post: function postlink(scope, element, attrs, controller) {                         // nothing                     }                 }             }         };     }); 

page directive's template ("page.html" templateurl property above)

<div ng-controller="pagectrl" >    ...    <!-- dynamic page content written div below -->    <div ng-bind-html-unsafe="pagecontent" >    ... </div> 

page controller

angular.module('myapp')   .controller('pagectrl', function ($scope) {          $scope.pagecontent = '';          $scope.$on( "receivedpagecontent", function(event, args) {             console.log( 'new page content received after db call' );             $scope.pagecontent = args.htmlstrfromdb;         });  }); 

that works. see page's html db rendered nicely in browser. when user flips next page, see next page's content, , on. far good.

the problem

the problem here want have interactive content inside of page's content. instance, html may contain thumbnail image where, when user clicks on it, angular should awesome, such displaying pop-up modal window. i've placed angular method calls (ng-click) in html strings in our database, of course angular isn't going recognize either method calls or directives unless somehow parses html string, recognizes them , compiles them.

in our db

content page 1:

<p>here's cool pic of lion. <img src="lion.png" ng-click="dosomethingawesone('lion', 'showimage')" > click on him see large image.</p> 

content page 2:

<p>here's snake. <img src="snake.png" ng-click="dosomethingawesone('snake', 'playsound')" >click make him hiss.</p> 

back in page controller, add corresponding $scope function:

page controller

$scope.dosomethingawesome = function( id, action ) {     console.log( "going " + action + " "+ id ); } 

i can't figure out how call 'dosomethingawesome' method within html string db. realize angular has parse html string somehow, how? i've read vague mumblings $compile service, , copied , pasted examples, nothing works. also, examples show dynamic content getting set during linking phase of directive. want page stay alive throughout life of app. receives, compiles , displays new content user flips through pages.

in abstract sense, guess trying dynamically nest chunks of angular within angular app, , need able swap them in , out.

i've read various bits of angular documentation multiple times, sorts of blog posts, , js fiddled people's code. don't know whether i'm misunderstanding angular, or missing simple, or maybe i'm slow. in case, use advice.

ng-bind-html-unsafe renders content html. doesn't bind angular scope resulted dom. have use $compile service purpose. created this plunker demonstrate how use $compile create directive rendering dynamic html entered users , binding controller's scope. source posted below.

demo.html

<!doctype html> <html ng-app="app">    <head>     <script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>     <script src="script.js"></script>   </head>    <body>     <h1>compile dynamic html</h1>     <div ng-controller="mycontroller">       <textarea ng-model="html"></textarea>       <div dynamic="html"></div>     </div>   </body>  </html> 

script.js

var app = angular.module('app', []);  app.directive('dynamic', function ($compile) {   return {     restrict: 'a',     replace: true,     link: function (scope, ele, attrs) {       scope.$watch(attrs.dynamic, function(html) {         ele.html(html);         $compile(ele.contents())(scope);       });     }   }; });  function mycontroller($scope) {   $scope.click = function(arg) {     alert('clicked ' + arg);   }   $scope.html = '<a ng-click="click(1)" href="#">click me</a>'; } 

Comments

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

.htaccess - Matching full URL in RewriteCond -