从数据库编译动态HTML字符串 形势
Angular应用程序中嵌套了一个名为Page的指令,由一个控制器支持,该控制器包含一个带有ng bind html不安全属性的div。这被分配给名为“pageContent”的$scope变量。该变量从数据库中动态生成HTML。当用户翻到下一页时,会调用DB,并且pageContent变量被设置为这个新的HTML,通过ng bind HTML在屏幕上呈现。代码如下: 页面指令从数据库编译动态HTML字符串 形势,html,dom,dynamic,angularjs,compilation,Html,Dom,Dynamic,Angularjs,Compilation,Angular应用程序中嵌套了一个名为Page的指令,由一个控制器支持,该控制器包含一个带有ng bind html不安全属性的div。这被分配给名为“pageContent”的$scope变量。该变量从数据库中动态生成HTML。当用户翻到下一页时,会调用DB,并且pageContent变量被设置为这个新的HTML,通过ng bind HTML在屏幕上呈现。代码如下: 页面指令 angular.module('myApp.directives') .directive('myPage',
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
}
}
}
};
});
页面指令的模板(“上面templateUrl属性中的Page.html”)
这很有效。我们从数据库中看到页面的HTML在浏览器中呈现得很好。当用户翻到下一页时,我们会看到下一页的内容,依此类推。到目前为止还不错
问题
这里的问题是,我们希望在页面内容中包含交互式内容。例如,HTML可能包含一个缩略图,当用户单击它时,Angular应该做一些很棒的事情,比如显示一个弹出模式窗口。我在数据库的HTML字符串中放置了Angular方法调用(ng click),但是Angular当然不会识别方法调用或指令,除非它以某种方式解析HTML字符串,识别并编译它们
在我们的数据库中
第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>
我不知道如何从数据库的HTML字符串中调用“doSomethingAwesome”方法。我意识到Angular必须以某种方式解析HTML字符串,但是如何解析呢?我读过一些关于$compile服务的含糊不清的文字,并复制和粘贴了一些示例,但没有任何效果。此外,大多数示例仅显示在指令的链接阶段设置的动态内容。我们希望页面在应用程序的整个生命周期中保持活力。它在用户翻页时不断接收、编译和显示新内容
从抽象意义上讲,我想你可以说,我们正在尝试在Angular应用程序中动态嵌套Angular块,并且需要能够将它们进行交换
我已经多次阅读了各种各样的Angle文档,以及各种各样的博客文章,JS对人们的代码进行了修改。我不知道我是否完全误解了,或者只是错过了一些简单的东西,或者可能是我太慢了。在任何情况下,我都可以使用一些建议。
ng bind html unsafe
仅将内容呈现为html。它不会将角度范围绑定到生成的DOM。为此,您必须使用$compile
服务。我创建它是为了演示如何使用$compile
创建一个指令来呈现用户输入的动态HTML并绑定到控制器的作用域。消息来源如下
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>
编译动态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>';
}
var-app=angular.module('app',[]);
应用程序指令('dynamic',函数($compile){
返回{
限制:“A”,
替换:正确,
链接:功能(范围、元素、属性){
作用域.$watch(attrs.dynamic,函数(html){
ele.html(html);
$compile(ele.contents())(范围);
});
}
};
});
函数MyController($scope){
$scope.click=函数(arg){
警报('单击'+参数);
}
$scope.html='';
}
在angular 1.2.10中,作用域。$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);
});
}
};
});
在谷歌讨论组中找到。对我有用
var $injector = angular.injector(['ng', 'myApp']);
$injector.invoke(function($rootScope, $compile) {
$compile(element)($rootScope);
});
你可以用
ng绑定html
指令动态绑定html。
但是,您必须通过$sce服务获取数据
请看现场演示
var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope,$sce){
$scope.getHtml=function(){
返回$sce.trustAsHtml(“Hi Rupesh Hi dfdfdfdf!sdafsdfsdfasdf”);
}
});
尝试下面的代码通过attr绑定html
试试这个element.html(scope.dynamic);
而不是element.html(attr.dynamic)非常感谢,Buu!创建attribute指令和添加scope watch函数是我所缺少的两件事。现在这一切都正常了,我想我将再次阅读指令和$compile,以便更好地理解引擎盖下发生的事情。我也是!Angular团队真的可以在这方面改进文档。
$compile(ele.contents())(范围)
-这一行解决了我不编译动态添加的角度组件的问题。谢谢。@BuuNguyen在teplateURL中假设如果您使用ng bind html包含一些动态HTMLPage,那么使用compile Doesn t work会从某些不安全的内容中产生错误另一方使用trustAsHTml只删除不安全的错误不编译,任何建议?我喜欢这个例子,但它没有让我的工作。我有一个开关语句,这是由于用户的选择而发生的,所以它是动态的。根据这一点,我想插入包含html的指令。如果我把指令放在自然引导阶段,它就可以工作。但是我有一个简单的例子,就是不触发---case'info':$scope.htmlString=$sce.trustAsHtml('dddzzz');break;---当我想做类似--$compile($sce.trustAsHtml('dddzzz'))的事情时;关于解决方法等有什么想法吗?您好,如果我使用element.html,它会返回我TypeError:无法调用null的方法'insertBefore'。所以在谷歌搜索了一段时间后,我发现我必须使用element.append,但如果我在多个地方使用该指令,它会生成多重html。因此,2个指令会生成4个相同的html代码。谢谢您的回答.我不会在你的位置上使用append,我今晚会看一看,然后再给你回复。老实说,我在很多地方都使用过这个指令
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>';
}
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);
});
}
};
});
var $injector = angular.injector(['ng', 'myApp']);
$injector.invoke(function($rootScope, $compile) {
$compile(element)($rootScope);
});
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>
.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);
});
}
};
});