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.
关注专栏
系列文章
Angular2基础之展示数据2 收藏, 142 浏览
Angular2基础之用户输入3 收藏, 215 浏览
Angular2基础之表单使用6 收藏, 311 浏览
掌握Angular2的依赖注入11 收藏, 470 浏览