AngularJS动态绑定HTML的方法分析


Posted in Javascript onNovember 07, 2016

本文实例讲述了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%E3%80%82

在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程序设计有所帮助。

Javascript 相关文章推荐
用javascript实现的仿Flash广告图片轮换效果
Apr 24 Javascript
javascript cookies 设置、读取、删除实例代码
Apr 12 Javascript
jQuery插件开发的五种形态小结
Mar 04 Javascript
jQuery实现图片渐入渐出切换展示效果
Aug 15 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
Jan 26 Javascript
原生Aajax 和jQuery Ajax 写法个人总结
Mar 24 jQuery
浅谈PDF.js使用心得
Jun 07 Javascript
浅析Vue.js中v-bind v-model的使用和区别
Dec 04 Javascript
js比较两个单独的数组或对象是否相等的实例代码
Apr 28 Javascript
详解如何在vue项目中使用layui框架及采坑
May 05 Javascript
使用p5.js临摹动态图形
Oct 23 Javascript
vue实现淘宝购物车功能
Apr 20 Javascript
基于JS分页控件实现简单美观仿淘宝分页按钮效果
Nov 07 #Javascript
easyui form validate总是返回false的原因及解决方法
Nov 07 #Javascript
jquery文字填写自动高度的实现方法
Nov 07 #Javascript
JS 全屏和退出全屏详解及实例代码
Nov 07 #Javascript
easyui tree带checkbox实现单选的简单实例
Nov 07 #Javascript
vue.js初学入门教程(2)
Nov 07 #Javascript
AngularJS递归指令实现Tree View效果示例
Nov 07 #Javascript
You might like
PHP随机生成随机个数的字母组合示例
2014/01/14 PHP
PHP fastcgi模式上传大文件(大约有300多K)报错
2014/09/28 PHP
php session_decode函数用法讲解
2019/05/26 PHP
Laravel find in set排序实例
2019/10/09 PHP
JQuery的ajax基础上的超强GridView展示
2009/09/18 Javascript
JavaScript 语言的递归编程
2010/05/18 Javascript
jQuery+CSS 半开折叠效果原理及代码(自写)
2013/03/04 Javascript
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
零基础搭建Node.js、Express、Ejs、Mongodb服务器及应用开发入门
2014/12/20 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
2015/02/28 Javascript
JavaScript Date对象详解
2016/03/01 Javascript
JS中sort函数排序用法实例分析
2016/06/16 Javascript
easyui combotree加载静态数据问题(选不上)解决方法
2016/12/26 Javascript
js实现百度登录框鼠标拖拽效果
2017/03/07 Javascript
Angular4学习之Angular CLI的安装与使用教程
2018/01/04 Javascript
vue 实现模糊检索并根据其他字符的首字母顺序排列
2019/09/19 Javascript
Python实现登录人人网并抓取新鲜事的方法
2015/05/11 Python
Python MySQL数据库连接池组件pymysqlpool详解
2017/07/07 Python
Python中支持向量机SVM的使用方法详解
2017/12/26 Python
python学习开发mock接口
2019/04/28 Python
把JSON数据格式转换为Python的类对象方法详解(两种方法)
2019/06/04 Python
python 将字符串完成特定的向右移动方法
2019/06/11 Python
详解Python3中setuptools、Pip安装教程
2019/06/18 Python
布隆过滤器的概述及Python实现方法
2019/12/08 Python
python如何通过pyqt5实现进度条
2020/01/20 Python
python上下文管理器异常问题解决方法
2021/02/07 Python
纯CSS3代码实现文字描边
2016/04/25 HTML / CSS
html5模拟平抛运动(模拟小球平抛运动过程)
2013/07/25 HTML / CSS
草莓网英国官网:Strawberrynet UK
2017/02/12 全球购物
SQL SERVER面试资料
2013/03/30 面试题
远程教育心得体会
2014/01/03 职场文书
自行车广告词大全
2014/03/21 职场文书
意向协议书范本
2014/04/23 职场文书
新闻发布会策划方案
2014/06/12 职场文书
新郎父亲婚礼致辞
2015/07/27 职场文书
Apache Linkis 中间件架构及快速安装步骤
2022/03/16 Servers