gir*_*nse 131 html dom compilation dynamic angularjs
嵌套在我们的Angular应用程序中的是一个名为Page的指令,由一个控制器支持,该控制器包含一个带有ng-bind-html-unsafe属性的div.这被分配给名为'pageContent'的$ scope var.此var从数据库中分配动态生成的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
}
}
}
};
});
Run Code Online (Sandbox Code Playgroud)
Page指令的模板(上面的templateUrl属性中的"page.html")
<div ng-controller="PageCtrl" >
...
<!-- dynamic page content written into the div below -->
<div ng-bind-html-unsafe="pageContent" >
...
</div>
Run Code Online (Sandbox Code Playgroud)
页面控制器
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;
});
});
Run Code Online (Sandbox Code Playgroud)
这样可行.我们在浏览器中看到来自数据库的页面的HTML很好地呈现.当用户翻到下一页时,我们会看到下一页的内容,依此类推.到现在为止还挺好.
这里的问题是我们希望在页面内容中包含交互式内容.例如,HTML可能包含一个缩略图,当用户点击它时,Angular应该做一些很棒的事情,比如显示一个弹出模式窗口.我在我们的数据库中的HTML字符串中放置了Angular方法调用(ng-click),但当然Angular不会识别方法调用或指令,除非它以某种方式解析HTML字符串,识别它们并编译它们.
在我们的DB中
第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>
Run Code Online (Sandbox Code Playgroud)
第2页的内容:
<p>Here's a snake. <img src="snake.png" ng-click="doSomethingAwesone('snake', 'playSound')" >Click to make him hiss.</p>
Run Code Online (Sandbox Code Playgroud)
回到Page控制器,然后我们添加相应的$ scope函数:
页面控制器
$scope.doSomethingAwesome = function( id, action ) {
console.log( "Going to do " + action + " with "+ id );
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何从数据库的HTML字符串中调用'doSomethingAwesome'方法.我意识到Angular必须以某种方式解析HTML字符串,但是如何?我读过关于$ compile服务的模糊咕噜声,并复制并粘贴了一些例子,但没有任何效果.此外,大多数示例显示仅在指令的链接阶段设置的动态内容.我们希望Page在应用程序的整个生命周期中保持活力.当用户翻阅页面时,它会不断接收,编译和显示新内容.
从抽象的意义上说,我猜你可以说我们正试图在Angular应用程序中动态嵌套Angular块,并且需要能够交换它们.
我已经多次阅读过Angular文档的各种内容,以及各种各样的博客文章,以及JS人们的代码.我不知道我是否完全误解了Angular,或者只是遗漏了一些简单的东西,或者说我很慢.无论如何,我可以使用一些建议.
Buu*_*yen 247
ng-bind-html-unsafe仅将内容呈现为HTML.它不会将Angular范围绑定到生成的DOM.您必须$compile为此目的使用服务.我创建了这个plunker来演示如何使用$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>
Run Code Online (Sandbox Code Playgroud)
的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>';
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*los 19
在角度1.2.10中,该行scope.$watch(attrs.dynamic, function(html) {返回了无效的字符错误,因为它试图观察其值attrs.dynamic是html文本.
我通过从scope属性中获取属性来修复它
scope: { dynamic: '=dynamic'},
Run Code Online (Sandbox Code Playgroud)
我的例子
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);
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
在谷歌讨论组中找到.适合我.
var $injector = angular.injector(['ng', 'myApp']);
$injector.invoke(function($rootScope, $compile) {
$compile(element)($rootScope);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
155906 次 |
| 最近记录: |