这里有新鲜出炉的 AngularJS 开发指南,程序狗速度看过来!
AngularJS 诞生于 Google 是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入,等等。
这篇文章主要介绍了 AngularJS 动态绑定 html 的方法, 结合实例形式分析了 AngularJS 实现动态绑定 HTML 的相关操作指令用法与使用注意事项, 需要的朋友可以参考下
本文实例讲述了 AngularJS 动态绑定 HTML 的方法。分享给大家供大家参考,具体如下:
在 web 前端开发中,我们经常会遇见需要动态的将一些来自后端或者是动态拼接的 HTML 字符串绑定到页面 DOM 显示,特别是在内容管理系统(CMS:是 Content Management System 的缩写),这样的需求,更是遍地皆是。
对于对 angular 的读者肯定首先会想到 ngBindHtml,对, angular 为我们提供了这个指令来动态绑定 HTML,它会将计算出来的表达式结果用 innerHTML 绑定到 DOM。但是,问题并不是这么简单。在 Web 安全中 XSS(Cross-site scripting,脚本注入攻击),它是在 Web 应用程序中很典型的计算机安全漏洞。XSS 攻击指的是通过对网页注入可执行客户端代码且成功地被浏览器执行,来达到攻击的目的,形成了一次有效 XSS 攻击,一旦攻击成功,它可能会获取到用户的一些敏感信息、改变用户的体验、诱导用户等非法行为,有时 XSS 攻击还会合其他攻击方式同时实施比如 SQL 注入攻击服务器和数据库、Click 劫持、相对链接劫持等实施钓鱼,它带来的危害是巨大的,也是 web 安全的头号大敌。更多的 Web 安全问题,请参考 wiki https://en.wikipedia.org/wiki/Cross-site_scripting。
在 angular 中默认是不相信添加的 HTML 内容,对于添加的 HTML 内容,首先必须利用 $sce.trustAsHtml,告诉 angular 这是可信的 HTML 内容。否则你将会得到 $sce:unsafe 的异常错误。
Error: [$sce:unsafe] Attempting to use an unsafe value in a safe context.
下面是一个绑定简单的 angular 链接的 demo:
HTML:
- <div ng-controller="DemoCtrl as demo">
- <div ng-bind-html="demo.html"></div>
- </div>
JavaScript:
- angular.module("com.ngbook.demo", [])
- .controller("DemoCtrl", ["$sce", function($sce) {
- var vm = this;
- var html = '<p>hello <a href="https://angular.io/">angular</a></p>';
- vm.html = $sce.trustAsHtml(html);
- return vm;
- }]);
对于简单的静态 HTML,这个问题就解决了。但对于复杂的 HTML,这里的复杂是指带有 angular 表达式、指令的 HTML 模板,对于它们来说,我们不仅希望绑定大 DOM 显示,同时还希望得到 angular 强大的双向绑定机制。ngBindHhtml 并不会和 $scope 关联双向绑定,如果在 HTML 中存在 ngClick、ngHref、ngSHow、ngHide 等 angular 指令,它们并不会被 compile,点击这些按钮,也不会发生任何反应,绑定的表达式也不会在更新。例如尝试将上次的链接变为:ng-href="demo.link",链接并不会被解析,在 DOM 看见的仍然会是原样的 HTML 字符串。
在 angular 中的所有指令要生效,都需要经过 compile,在 compile 中包含了 pre-link 和 post-link,连接上特定行为,才能工作。大部分情况下 compile,是会在 angular 启动时,自动 compile 的。但如果是对于动态添加的模板,则需要手动的 compile。angular 中为我们提供了 $compile 服务来实现这一功能。下面是一个比较通用的 compile 例子:
HTML:
- <body ng-controller="DemoCtrl as demo">
- <dy-compile html="{{demo.html}}">
- </dy-compile>
- <button ng-click="demo.change();">
- change
- </button>
- </body>
JavaScript:
- angular.module("com.ngbook.demo", [])
- .directive("dyCompile", ["$compile", function($compile) {
- return {
- replace: true,
- restrict: 'EA',
- link: function(scope, elm, iAttrs) {
- var DUMMY_SCOPE = {
- $destroy: angular.noop
- },
- root = elm,
- childScope,
- destroyChildScope = function() {
- (childScope || DUMMY_SCOPE).$destroy();
- };
- iAttrs.$observe("html", function(html) {
- if (html) {
- destroyChildScope();
- childScope = scope.$new(false);
- var content = $compile(html)(childScope);
- root.replaceWith(content);
- root = content;
- }
- scope.$on("$destroy", destroyChildScope);
- });
- }
- };
- }])
- .controller("DemoCtrl", [function() {
- var vm = this;
- vm.html = '<h2>hello : <a ng-href="{{demo.link}}">angular</a></h2>';
- vm.link = 'https://angular.io/';
- var i = 0;
- vm.change = function() {
- vm.html = '<h3>change after : <a ng-href="{{demo.link}}">' + (++i) + '</a></h3>';
- };
- }]);
这里创建了一个叫 dy-compile 的指令,它首先会监听绑定属性 html 值的变化,当 html 内容存在的时候,它会尝试首先创个一个子 scope,然后利用 $compile 服务来动态连接传入的 html,并替换掉当前 DOM 节点;这里创建子 scope 的原因,是方便在每次销毁 DOM 的时,也能容易的销毁掉 scope,去掉 HTML compile 带来的 watchers 函数,并在最后的父 scope 销毁的时候,也会尝试销毁该 scope。
因为有了上边的 compile 的编译和连接,则 ngHref 指令就可以生效了。这里只是尝试给出动态 compile angular 模块的例子,具体的实现方式,请参照你的业务来声明特定的 directive。
希望本文所述对大家 AngularJS 程序设计有所帮助。
来源: http://www.phperz.com/article/17/0430/330608.html