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
Post a Comment