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

(0)

相关推荐

  • 详解Angular.js数据绑定时自动转义html标签及内容

    angularJS在进行数据绑定时默认是以字符串的形式数据,也就是对你数据中的html标签不进行转义照单全收,这样提高了安全性,防止html标签的注入攻击,但有时候需要,特别是从数据库读取带格式的文本时,无法正常的显示在页面中. 而要对html进行转义,则需要在数据绑定的html标签中使用ng-bind-html属性,该属性依赖与$sanitize,也就是需要引入angular-sanitize.js文件,并在module定义时注入该服务ngSanitize.比如: html: <span ng

  • Angular4绑定html内容出现警告的处理方法

    前言 众所周知在Web前端开发中,我们经常会遇见需要动态的将一些来自后端或者是动态拼接的HTML字符串绑定到页面DOM显示,特别是在内容管理系统(CMS:是Content Management System的缩写),这样的需求,更是遍地皆是.但是最近在Angular4绑定html内容的时候出现了警告,通过查找相关资料终于解决了,下面给同样遇到这个问题的朋友们分享下,话不多说了,来一起看看详细的介绍吧. 绑定html内容 如果用正常的方法去绑定的话,可能会出再这种警告 <div [innerHTM

  • AngularJS动态绑定HTML的方法分析

    本文实例讲述了AngularJS动态绑定HTML的方法.分享给大家供大家参考,具体如下: 在Web前端开发中,我们经常会遇见需要动态的将一些来自后端或者是动态拼接的HTML字符串绑定到页面DOM显示,特别是在内容管理系统(CMS:是Content Management System的缩写),这样的需求,更是遍地皆是. 对于对angular的读者肯定首先会想到ngBindHtml,对,angular为我们提供了这个指令来动态绑定HTML,它会将计算出来的表达式结果用innerHTML绑定到DOM.

  • AngularJS路由切换实现方法分析

    本文实例讲述了AngularJS路由切换实现方法.分享给大家供大家参考,具体如下: 之前有在服务器端接触到angular路由切换,今天想在本地实现路由,捣鼓半天终于成功了,特把步骤整理分享下,免得大家走弯路! 1.首先引入angular.min.js和angular-route.min.js 2.然后我们来写框架index.html,index里面装的是所有页面都有的nav导航和footer页脚(我这个demo里只有nav),模板文件page1.html,page2.html,也就是中间路由切换

  • AngularJS的$location使用方法详解

    AngularJS的$location使用方法详解 一.配置config app.config([ '$locationProvider', function($locationProvider) { $locationProvider.html5Mode({ //设置为html5Mode(模式),当为false时为Hashbang模式 enabled : true, //是否需要加入base标签,这里设置为false,设置为true时,需在html的head配置<base href="&

  • AngularJS身份验证的方法

    权限的设计中比较常见的就是RBAC基于角色的访问控制,基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合.每一种角色对应一组相应的权限. 一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限.这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只要分配用户相应的角色即可,而且角色的权限变更比用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销. 在Angular构建的单页面应用中,要实现这样的架构我们需要额外多做一些事

  • AngularJS折叠菜单实现方法示例

    本文实例讲述了AngularJS折叠菜单实现方法.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="bootstrap.min.css&quo

  • JSP页面中文参数的传递(get和post方法分析)

    在项目中,我们经常遇到需要在JSP页面切换中传递中文字符.这主要有两种方式. ◆URL方式 例如: http://website/test1.jsp?act=add&type=苹果&param=%20D%20B ◆FORM方式 例如: 复制代码 代码如下: ﹤form name=test   mehtod="post"﹥   ﹤input type=hidden name=text2 value="中文"﹥   ﹤input type=text na

  • 基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析

    这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能,总结前端学习过的内容. 技术:NodeJS.Express.Monk.MongoDB.AngularJS.BootStrap.跨域 效果: 一.Bootstrap Bootstrap是一个UI框架,它支持响应式布局,在PC端与移动端都表现不错. Bootstrap是Twitter推出的一款简洁.直

  • angularjs中的$eval方法详解

    在controller中定义了一个变量 $scope.a_1 = "abc"; 想在view里面动态输出,因为这个数字是动态的,这么输出肯定是不行的{{'a_' + '1'}},因为输出来的是a_1这个字符串,而不是a_1这个变量的值 想输出a_1这个变量的值,可以使用$eval方法:{{$eval('a_' + '1')}} $eval是作为scope的方法来使用的,在controller中使用的话,是这么使用:$scope.$eval() 以上这篇angularjs中的$eval方

  • AngularJS 异步解决实现方法

    AngularJS 异步解决实现方法 Angular 的异步处理的真的很不错.基于消息广播的方式,并且可以向上传递,基本上解决了不同模块,不同controller之间不方便异步的问题. 场景一:通过回调函数进行异步操作(该情况下不用消息广播的机制) 这种情况的特点是直接传递一个回调函数给异步操作就可以了,等异步操作完执行回调. 比如:controller通过server异步取数据,等取完数据进行一系列的操作,这个时候就可以把操作封装到函数中,传递给异步操作函数. controller代码片段举例

  • Java遍历集合方法分析(实现原理、算法性能、适用场合)

    概述 Java语言中,提供了一套数据集合框架,其中定义了一些诸如List.Set等抽象数据类型,每个抽象数据类型的各个具体实现,底层又采用了不同的实现方式,比如ArrayList和LinkedList. 除此之外,Java对于数据集合的遍历,也提供了几种不同的方式.开发人员必须要清楚的明白每一种遍历方式的特点.适用场合.以及在不同底层实现上的表现.下面就详细分析一下这一块内容. 数据元素是怎样在内存中存放的? 数据元素在内存中,主要有2种存储方式: 1.顺序存储,Random Access(Di

随机推荐