Angular模板与表达式的绑定

https://segmentfault.com/a/1190000003712937

我们以下使用的angular
的版本是1.3.x,完整的代码在文章的最后面,在线的例子demo注意,我下面给出的代码示例只是截取了一部分,完整的部分在文章的最后面

1.首先我们最常使用的一个绑定表达式的指令是ngBind
,比如在一个div
标签中我们可以这样使用:
<div ng-bind="vm.info"></div>

这样就把控制器中的vm.info
的值绑定到这个div
标签里面了,使用这个指令还有一个好处就是在页面还没有完全渲染好的情况下,是不会出现Angular的{{}}
解析符号的,它隐藏了Angular解析表达式的过程。如果你使用了下面的方法,
<div>{{vm.info}}</div>

在网速不是很好的情况下,就会出现{{}}
解析符号,给用户带来不好的体验。
2.下一个绑定表达式的指令就是ngBindTemplate
了,这个指令与上一个指令的最大不同之处是:ngBindTemplate
可以绑定多个表达式,这样就有一个好处,在一些元素中,比如title
和option
是不可以包含sapn
元素的,这时候如果需要多个变量的话,ngBindTemplate
就是很必须的。

<div ng-bind-template="{{vm.info}} {{vm.msg}}"></div>

还要注意一点就是,这个指令的用法,多个模型变量是用{{}}
括起来的。
3.接下来的一些是关于模板的绑定,第一个比较常用的是ngBindHtml
,从指令的名字就可以看出来,这个指令是绑定一段html
的,那么这个指令该如何使用呢?我们来研究一下,首先,我们需要在控制器定义一段html
代码,如下所示:
vm.html = '<div class="container">\ <div class="title">{{vm.info}}</div>\ <div class="content">content</div>\ </div>';

然后我们就会很自然地想到按照下面的方法去使用这个指令:
<div ng-bind-html="vm.html"></div>

但是当你在浏览器上运行的时候,却发现浏览器给你报了一个错误,如下所示:



说你在一个安全的上下文中使用了不安全的值,怎么解决这个问题呢?我们可以手动的将我们定义的那段html
代码,变成Angular信任的值,具体的方法是在控制器定义一个方法如下所示:
function trust_my_html(str){ return $sce.trustAsHtml(str); }

然后在html
中可以这样使用:
<div ng-bind-html="vm.trust_my_html(vm.html)"></div>

4.上面的方法在一定程度上解决了模板的绑定问题,但是,还有一个小问题,就是模板中的表达式并没有被解析,你可以看看我写的那个demo,所以要想解决这个问题,就是有两个办法,首先就是你自己写一个指令,当绑定模板的时候,将模板中的表达式也给解析了,第二个办法就是使用别人的插件,我看到一个比较好的插件,名字叫做angular-bind-html-compile
,我们在我们的主模块中注入这个依赖就可以使用这个指令了,使用方法如下:
<div bind-html-compile="vm.html"></div>

这样一来,我们模块中的表达式也可以被解析了。还有需要注意,使用这个指令就不需要我们手动的将那段html
片段变成Angular信任的值了。
5.当我们仔细看了看上面所说的那个指令,发现也不是那么的难,还不如我们自己写一个呢,不然还要引入他的文件,太费事了,具体的代码如下:
function compileBindHtml($compile){ var directive = { restrict: 'AE', link:linkFunc }; return directive; function linkFunc(scope, elements, attrs){ var func = function(){ return scope.$eval(attrs.compileBindHtml); }; scope.$watch(func, function(newValue){ elements.html(newValue); $compile(elements.contents())(scope); }) } }

我们来看看这个指令,在链接函数中,我们使用$watch
监测func
函数的返回值,func
函数的返回值是一个被$eval
的属性值,也就是我们的模板值,然后当检测到有变化的时候,就将我们的模板值放置到含有这个指令的html
标签中,然后在使用$compile
服务将我们的模板给编译了。看看其实也不是那么难的。
6.最后一个可以用来绑定模板的指令是ngInclude
,这个指令使用的频率相对来说比较高一点,那么这个指令怎么使用呢?我们一起来研究一下。
方法一,将模板写在html
文件中,这个过程要通过使用script
指令来实现,如下所示的一个例子:

<script type="text/ng-template" id="template-1"> <div class="container"> <div class="title">{{vm.info}}</div> <div class="content">content</div> </div> </script>

这里来讲解一下怎么使用这个script
指令,首先它的type
属性值必须是ng-template
,然后id
值是它的一个标记或者索引,当你需要在html
中使用它的时候就要使用这个id
的值来引用这段模板。
方法二,将模板写在js
文件中,通过使用$templateCache
服务,来写我们的模板,具体的用法如下:

function configFuc($templateCache){ var template = '<div class="container">\ <div class="title">{{vm.info}}</div>\ <div class="content">content</div>\ </div>'; $templateCache.put('template-2', template); }

我们的模板的索引是template-2
,具体的内容就是template
变量里面的内容。
在html
里面使用的方法如下所示:
<div ng-include="'template-1'"></div> <div ng-include="'template-2'"></div>

使用ngInclude
的另一个好处就是模板里面的表达式是会被解析的。
完整的代码:
index.html

<body ng-controller="MyController as vm"> <script type="text/ng-template" id="template-1"> <div class="container"> <div class="title">{{vm.info}}</div> <div class="content">content</div> </div> </script> <h1 class="title">ngInclude <span>VS</span> ngBindHtml <span>VS</span> ngBind <span>VS</span> ngBindTemplate</h1> <hr/> <h3>ngBind</h3> <div ng-bind="vm.info"></div> <hr/> <h3>ngBindTemplate</h3> <div ng-bind-template="{{vm.info}} {{vm.msg}}"></div> <hr/> <h3>ngBindHtml</h3> <div ng-bind-html="vm.trust_my_html(vm.html)"></div> <div compile-bind-html="vm.html"></div> <div bind-html-compile="vm.html"></div> <hr/> <h3>ngInclude</h3> <div ng-include="'template-1'"></div> <div ng-include="'template-2'"></div></body>

index.js

(function(){ angular.module('MyApp', ['angular-bind-html-compile']) .run(configFuc) .controller('MyController', MyController) .directive('compileBindHtml', compileBindHtml); configFuc.$inject = ['$templateCache']; MyController.$inject = ['$sce']; compileBindHtml.$inject = ['$compile']; function configFuc($templateCache){ var template = '<div class="container">\ <div class="title">{{vm.info}}</div>\ <div class="content">content</div>\ </div>'; $templateCache.put('template-2', template); } function MyController($sce){ var vm = this; vm.info = 'Hello,World'; vm.msg = 'Thank You!'; vm.html = '<div class="container">\ <div class="title">{{vm.info}}</div>\ <div class="content">content</div>\ </div>'; vm.trust_my_html = trust_my_html; vm.get_trust_html = get_trust_html; function trust_my_html(str){ return $sce.trustAsHtml(str); } function get_trust_html(str){ return $sce.getTrustedHtml(str); } } function compileBindHtml($compile){ var directive = { restrict: 'AE', link:linkFunc }; return directive; function linkFunc(scope, elements, attrs){ var func = function(){ return scope.$eval(attrs.compileBindHtml); }; scope.$watch(func, function(newValue){ elements.html(newValue); $compile(elements.contents())(scope); }) } }})();

style.css

h1.title{ text-align: center;}h1.title span{ color: #CCC;}.container{ width: 100%; height: 60px;}.container .title{ height: 20px; background-color: #b3d4fc; font-size: 20px; line-height: 20px; text-align: center;}.container .content{ height: 40px; background-color: #0000FF; font-size: 15px; line-height: 40px; text-align: center;}h3{ text-align: center; color: #FF0000;}div{ text-align: center;}

参考的资料:How to make ng-bind-html compile angularjs code

2015年09月06日发布
更多****

4 推荐
收藏

你可能感兴趣的文章
Angularjs标签模板加载原理 4 收藏,2.8k 浏览

浅谈AngularJS模板 22 收藏,5.5k 浏览

AngularJS 使用感受 4 收藏,3k 浏览

本文 禁止转载,如有需要请先联系作者。

讨论区

提交评论
**

×
评论支持部分 Markdown 语法:bold
italic
link

引用
code

  • 列表
    。同时,被你 @ 的用户也会收到通知

本文隶属于专栏
AngularJS
Classical is something not fade,but grow more precious with time pass by,so is dream id dream.

dreamapplehappy作者
关注专栏

系列文章
Angular2基础之展示数据2 收藏, 142 浏览

Angular2基础之用户输入3 收藏, 215 浏览

Angular2基础之表单使用6 收藏, 311 浏览

掌握Angular2的依赖注入11 收藏, 470 浏览

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容