从数据库编译dynamicHTMLstring

情况

在Angular应用程序中嵌套的是一个名为Page的指令,由一个控制器支持,该控制器包含一个带有ng-bind-html-unsafe属性的div。 这被分配给一个名为“pageContent”的$ scope var。 这个var从数据库中获取dynamic生成的HTML。 当用户翻到下一页时,调用DB,pageContent var被设置为这个新的HTML,通过ng-bind-html-unsafe在屏幕上显示。 代码如下:

页指令

angular.module('myApp.directives') .directive('myPage', function ($compile) { return { templateUrl: 'page.html', restrict: 'E', compile: function compile(element, attrs, transclude) { // does nothing currently return { pre: function preLink(scope, element, attrs, controller) { // does nothing currently }, post: function postLink(scope, element, attrs, controller) { // does nothing currently } } } }; }); 

Page指令的模板 (上面的templateUrl属性中的“page.html”)

 <div ng-controller="PageCtrl" > ... <!-- dynamic page content written into the div below --> <div ng-bind-html-unsafe="pageContent" > ... </div> 

页面控制器

 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; }); }); 

这样可行。 我们在浏览器中看到了页面中来自数据库的HTML。 当用户翻到下一页时,我们会看到下一页的内容,依此类推。 到现在为止还挺好。

问题

这里的问题是我们希望在页面内容中包含交互式内容。 例如,HTML可能包含一个缩略图,当用户点击它的时候,Angular应该做一些很棒的事情,例如显示一个popup式模式窗口。 我在数据库的HTMLstring中放置了Angular方法调用(ng-click),但是当然Angular不会识别方法调用或指令,除非它以某种方式分析HTMLstring,识别并编译它们。

在我们的数据库

内容为第1页:

 <p>Here's a cool pic of a lion. <img src="lion.png" ng-click="doSomethingAwesone('lion', 'showImage')" > Click on him to see a large image.</p> 

第2页的内容:

 <p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p> 

返回页面控制器,然后添加相应的$ scope函数:

页面控制器

 $scope.doSomethingAwesome = function( id, action ) { console.log( "Going to do " + action + " with "+ id ); } 

我不知道如何从数据库的HTMLstring中调用“doSomethingAwesome”方法。 我意识到Angular必须以某种方式parsingHTMLstring,但是如何? 我已经阅读了关于$ compile服务的模糊的混淆,并且复制并粘贴了一些示例,但是没有任何效果。 另外,大多数示例显示的是dynamic内容只在指令的链接阶段被设置。 我们希望页面在应用程序的整个生命周期中保持活力。 它不断地接收,编译和显示新的内容,当用户翻页时。

从抽象意义上讲,我想你可以说我们正在尝试在Angular应用程序中dynamic地嵌套Angular块,并且需要能够将它们交换出来。

我已经多次阅读了Angular文档的各个部分,以及各种博客post,以及JS用人们的代码弄了个手脚。 我不知道我是否完全误解了Angular,或者只是错过了一些简单的东西,或者我很慢。 无论如何,我可以用一些build议。

ng-bind-html-unsafe只将内容呈现为HTML。 它不会将Angular范围绑定到DOM。 你必须使用$compile服务来达到这个目的。 我创build了这个工具来演示如何使用$compile来创build一个指令来渲染用户input的dynamicHTML并绑定到控制器的作用域。 信息来源如下。

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>'; } 

在angular度1.2.10的行scope.$watch(attrs.dynamic, function(html) {返回一个无效的字符错误,因为它试图观察的HTML文本attrs.dynamic的值。

我通过从scope属性中获取属性来解决这个问题

  scope: { dynamic: '=dynamic'}, 

我的例子

 angular.module('app') .directive('dynamic', function ($compile) { return { restrict: 'A', replace: true, scope: { dynamic: '=dynamic'}, link: function postLink(scope, element, attrs) { scope.$watch( 'dynamic' , function(html){ element.html(html); $compile(element.contents())(scope); }); } }; }); 

在谷歌讨论组中find。 为我工作。

 var $injector = angular.injector(['ng', 'myApp']); $injector.invoke(function($rootScope, $compile) { $compile(element)($rootScope); }); 

您可以使用

ng-bind-html https://docs.angularjs.org/api/ng/service/ $ sce

指令来dynamic地绑定html。 但是,您必须通过$ sce服务获取数据。

请参阅http://plnkr.co/edit/k4s3Bx上的现场演示;

 var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope,$sce) { $scope.getHtml=function(){ return $sce.trustAsHtml("<b>Hi Rupesh hi <u>dfdfdfdf</u>!</b>sdafsdfsdf<button>dfdfasdf</button>"); } }); <body ng-controller="MainCtrl"> <span ng-bind-html="getHtml()"></span> </body> 

尝试下面的代码通过attr绑定html

 .directive('dynamic', function ($compile) { return { restrict: 'A', replace: true, scope: { dynamic: '=dynamic'}, link: function postLink(scope, element, attrs) { scope.$watch( 'attrs.dynamic' , function(html){ element.html(scope.dynamic); $compile(element.contents())(scope); }); } }; }); 

试试这个element.html(scope.dynamic); 比element.html(attr.dynamic);