Angular.js指令学习中一些重要属性的用法教程


Posted in Javascript onMay 24, 2017

Angular指令

定义一个指令的方法非常简单,只需要调用`directive`方法即可:

var app=angular.module('myapp',[]);
 app.directive(name,fn)

1. 基础指令

var app=angular.module('myapp',[]);
 app.run(function($templateCache){
  $templateCache.put('cache','<h3>模板内容来源于缓存</h3>')
 });
 app.directive('tsHello',function(){
  return{
  restrict:'EAC',
  template:'<h3>Hello,directive</h3>'
  }
 })
 app.directive('tsTplfile',function(){
  return{
  restrict:'EAC',
  templateUrl:'/static/tpl.html'
  }
 });
 app.directive('tsTplscript',function(){
  return {
  restrict:'EAC',
  templateUrl:'tpl',
  replace:true
  }
 });
 //templateUrl属性值是添加的缓存名称,加速文件访问
 app.directive('tsTplcache',function(){
  return{
  restrict:'EAC',
  templateUrl:'cache'
  }
 })
 </script>

2. 重要指令

2.1 transclude

<script type="text/ng-template" id='tpl'>
 <div>
  <input type="text" ng-model='text' />
  <div ng-transclude></div>
 </div>
 </script>
 <ts-tplscript>{{text}}</ts-tplscript>
 <script type="text/javascript">
 var app=angular.module('myapp',[]);
 app.directive('tsTplscript',function(){
  return {
  restrict:'EAC',
  templateUrl:'tpl',
  transclude:true
  }
 });
 </script>

关于transclude更加详细的介绍,参见另外一篇文章

2.2 link

link属性的值是一个函数,在该函数中可以操控DOM元素的对象,包括绑定元素的各类事件,定义事件触发时执行的内容等:

link:function(scope,iEle,iAttrs)

link 函数包括3个主要的参数,其中,scope参数表示指令所在的作用域,它的功能与页面中控制器注入的作用域是相同的,iEle参数表示指令中的元素,该元素可以通过Angular内部封装的jqLite进行调用,jqLite相当于是一个压缩版的jQuery,包含了主要的元素操作API,在语法上与jQuery类似,iAttrs参数表示指令元素的属性集合,通过这个参数可以获取元素中的各类属性。

<script type="text/ng-template" id='tpl'>
 <button>单击按钮</button>
 </script>
 <div>
 <ts-tplscript></ts-tplscript>
 <div>{{content}}</div>
 </div>
 <script type="text/javascript">
 var app=angular.module('myapp',[]);
 app.directive('tsTplscript',function(){
  return {
  restrict:'EAC',
  templateUrl:'tpl',
  replace:true,
  link:function(scope,iEle,iAttrs){
   iEle.bind('click',function(){
   scope.$apply(function(){
    scope.content='这是点击后的内容';
   })
   iAttrs.$$element[0].disabled=true;//这里也可以替换为this.disabled=true;
   });
  }
  }
 });
 </script>

自定义tsTplscript指令时,在指令返回的对象中添加了link属性,用于绑定和执行DOM元素的各类事件,在属性值执行的函数中,添加scope,iEle,iAttrs三个参数,在指令执行的过程中,由于指令中并没有定义scope属性,因此,scope参数默认就是元素外层父级scope属性,即控制器注入的$scope属性。

此外,iEle参数就是被指令模板替换后的<button>元素,由于在Angular中引入了jqLite,因此可以直接调用bind方法绑定元素的各类事件,在执行事件函数的时候,调用了scope属性的$apply方法,它的功能是在执行完方法中的函数之后,重新渲染页面视图。

iAttrs参数是指令元素的属性集合,$$element则表示与属性对应的元素集合,该集合是一个数组。

2.3 compile

<div ng-controller='myController'>
 <ts-a>
  <ts-b>
  {{tip}}
  </ts-b>
 </ts-a>
 </div>
 <script type="text/javascript">
 var app=angular.module('myapp',[]);
 app.controller('myController',function($scope){
  $scope.tip='跟踪compile执行过程 ';
 });
 app.directive('tsA',function(){
  return {
  restrict:'EAC',
  compile:function(tEle,tAttrs,trans){
   console.log('正在编译A指令');
   //返回一个对象时,对象中包含两个名为`pre`和`post`的方法函数
   return {
   pre:function(scope,iEle,iAttrs){
    console.log('正在执行A中的pre函数');
   },
   post:function(scope,iEle,iAttrs){
    console.log('正在执行A中的post函数');
   }
   }
  }
  }
 });
 app.directive('tsB',function(){
  return {
  compile:function(tEle,tAttrs,trans){
   console.log('正在编译B指令');
   return{
   pre:function(scope,iEle,iAttrs){
    console.log('正在执行B中的pre函数');
   },
   post:function(scope,iEle,iAttrs){
    console.log('正在执行B中的post函数');
   }
   }
  }
  }
 })
 </script>

控制台依次输出:

正在编译A指令
 正在编译B指令
 正在执行A中的pre函数
 正在执行B中的pre函数
 正在执行B中的post函数
 正在执行A中的post函数

2.4 scope

2.4.1 当scope值是布尔类型

scope属性自定义指令时,默认值就是布尔类型的,初始值为false,在这种情况下,指令中的作用域就是指令元素所在的作用域,如果scope属性值为false,表示不创建新的作用域,直接继承父级作用域,二者数据完全相同,一方有变化,另外一方面将会自动变化。

如果scope属性值为true,表示子作用域是独立创建的,当它的内容发生变化时,并不会修改父作用域中的内容,不仅如此,一旦某个属性被子作用域进行了重置,那么,即使父作用域中的内容变化了,子作用域对应的内容也不会随之变化。

<script type="text/ng-template" id='tpl'>
 <div>{{message}}</div>
 <button ng-transclude></button>
 </script>
 <div>
 <input type="text" ng-model='message' />
 <ts-message>固定</ts-message>
 </div>
 <script type="text/javascript">
 var app=angular.module('myapp',[]);
 app.directive('tsMessage',function(){
  return {
  restrict:'EAC',
  templateUrl:'tpl',
  transclude:true,
  scope:true,
  link:function(scope,iEle,iAttrs){
   iEle.bind('click',function(){
   scope.$apply(function(){
    scope.message='这是单击按钮后的值。'
   })
   })
  }
  }
 });

 </script>

在单击按钮之前,子作用域中的值随父作用域改变,当单击按钮之后,手动重置了子作用域中的'message'遍历,但与变量绑定的父作用域的内容并没有变化,并且子作用域也不再随父作用域发生变化。

2.4.2 当scope值是对象

如果将scope属性值设置成一个JSON对象,那么父作用域与子作用域完全独立,不存在任何关联。

当指令中的scope属性值是JSON对象时,如果子作用域需要添加属性,必须先添加指令中的link函数,然后通过函数中的scope对象进行添加,如果在子作用域中,要绑定或调用父父作用域中的属性和方法,则需要在scope属性对应的JSON对象值中添加绑定策略。

严格来说,在JSON对象中添加的有3种绑定策略:@ = &

1、@

@绑定与将scope值设为true,有许多相同的地方,唯一不同之处在于,@绑定在子作用域充值属性之后,再返回修改父作用域对应属性内容时,子作用域对应的属性,同样还是会随之发生变化,而使用scope:true,则不会发生这一步。

2、=

=绑定的功能是创建一个父与子作用域可以同时共享的属性,即当父作用域修改了该属性,子作用域也随之变化,反之亦然,两个作用域间完全共享和同步。

3、&

&绑定的功能是可以在独立的子作用域中直接调用父作用域的方法,在调用时可以向函数传递参数,这种功能的好处在于,避免重复编写功能相同的代码,只需要进行简单的绑定设置,就可以使指令执行后,轻松调用控制器中的方法。

<script type="text/ng-template" id='tpl'>
 <div>
  <span>姓名:{{textName}}</span>
  <span>年龄:{{textAge}}</span>
 </div>
 <button ng-transclude></button>
 </script>
 <div ng-controller="myController">
 姓名:<input type="text" ng-model='text_name' /><br>
 年龄:<input type="text" ng-model='text_age' /><br>
 <div>{{tip}}</div>
 <ts-json a-attr="{{text_name}}" b-attr="text_age" reset="reSet()">重置</ts-json>
 </div>
 <script type="text/javascript">
 var app=angular.module('myapp',[]);
 app.controller('myController',function($scope){
  $scope.reSet=function(){
  $scope.tip='姓名与年龄重置成功!';
  }
 });
 app.directive('tsJson',function(){
  return {
  restrict:'EAC',
  templateUrl:'tpl',
  transclude:true,
  scope:{
   textName:'@aAttr',
   textAge:'=bAttr',
   reSet:'&reset'
  },
  link:function(scope,iEle,iAttrs){
   iEle.bind('click',function(){
   scope.$apply(function(){
    scope.reSet();
    scope.textName='张三';
    scope.textAge='20';
   })
   })
  }
  }
 });

 </script>

绑定的过程:

先在指令元素中创建a-attr或b-attr属性,由于HTML不区分大小写,因此使用-隔开。

需要注意的是:由于在指令中绑定策略不同,在指令元素中,属性绑定属性值也会有些变化,使用@绑定的属性,绑定属性值的方式为双大括号{{}},而使用=绑定的属性,绑定属性值的方式为等于号=,不需要双大括号.

2.5 require和controller

当一个子元素需要与一个父元素指令通信时,就需要添加并使用这两个属性值。

<div>
 <ts-parent>
  <div>{{ptip}}</div> 
  <ts-child>
  <div>{{ctip}}</div>
  </ts-child>
  <button ng-click='click()'>换位</button>
 </ts-parent>
 </div>
 <script type="text/javascript">
 var app=angular.module('myapp',[]);
 app.directive('tsParent',function(){
  return {
  restrict:'EAC',
  controller:function($scope,$compile,$http){
   this.addChild=function(c){
   $scope.ptip='今天天气不错!';
   $scope.click=function(){
    $scope.tmp=$scope.ptip;
    $scope.ptip=c.ctip;
    c.ctip=$scope.tmp;
   }
   }
  }
  }
 });
 app.directive('tsChild',function(){
  return {
  restrict:'EAC',
  require:'^?tsParent',
  link:function(scope,iEle,iAttrs,ctrl){
   scope.ctip='气温正好18摄氏度';
   ctrl.addChild(scope);
  }
  }
 })
 </script>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
解javascript 混淆加密收藏
Jan 16 Javascript
js保存当前路径(cookies记录)
Dec 14 Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
Jan 09 Javascript
javascript学习总结之js使用技巧
Sep 02 Javascript
Javascript的表单验证-揭开正则表达式的面纱
Mar 18 Javascript
Bootstrap框架动态生成Web页面文章内目录的方法
May 12 Javascript
快速掌握jQuery插件WebUploader文件上传
Nov 07 Javascript
Vue v2.5 调整和更新不完全问题
Oct 24 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
Apr 26 jQuery
详解微信小程序网络请求接口封装实例
May 02 Javascript
vue实现的上拉加载更多数据/分页功能示例
May 25 Javascript
javascript中contains是否包含功能实现代码(扩展字符、数组、dom)
Apr 07 Javascript
jquery append与appendTo方法比较
May 24 #jQuery
php 修改密码实现代码
May 24 #Javascript
详解VueJs前后端分离跨域问题
May 24 #Javascript
angular.js指令中transclude选项及ng-transclude指令详解
May 24 #Javascript
angular directive的简单使用总结
May 24 #Javascript
深入理解JavaScript 参数按值传递
May 24 #Javascript
详解Angular 4.x NgTemplateOutlet
May 24 #Javascript
You might like
php简单对象与数组的转换函数代码(php多层数组和对象的转换)
2011/05/18 PHP
PHP数组循环操作详细介绍 附实例代码
2013/02/03 PHP
session在php5.3中的变化 session_is_registered() is deprecated in
2013/11/12 PHP
PHP INT类型在内存中占字节详解
2019/07/20 PHP
使用正则替换变量
2007/05/05 Javascript
JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
2012/02/27 Javascript
什么是 AngularJS?AngularJS简介
2014/12/06 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
2015/07/27 Javascript
jQuery实现的分子运动小球碰撞效果
2016/01/27 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
使用Javascript判断浏览器终端设备(PC、IOS(iphone)、Android)
2017/01/04 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
jquery实现简单实用的轮播器
2017/05/23 jQuery
jQuery实现的鼠标响应缓冲动画效果示例
2018/02/13 jQuery
vuedraggable+element ui实现页面控件拖拽排序效果
2020/07/29 Javascript
Vue使用.sync 实现父子组件的双向绑定数据问题
2019/04/04 Javascript
js通过循环多张图片实现动画效果
2019/12/19 Javascript
解决vue中el-tab-pane切换的问题
2020/07/19 Javascript
浅谈vue 多个变量同时赋相同值互相影响
2020/08/05 Javascript
[00:09]DOTA2新版本PA至宝特效动作展示
2014/11/19 DOTA
[00:33]DOTA2上海特级锦标赛 CDEC战队宣传片
2016/03/04 DOTA
Django框架下在URLconf中指定视图缓存的方法
2015/07/23 Python
Python使用正则表达式抓取网页图片的方法示例
2017/04/21 Python
Python在groupby分组后提取指定位置记录方法
2018/04/20 Python
python采集微信公众号文章
2018/12/20 Python
Docker部署Python爬虫项目的方法步骤
2020/01/19 Python
CSS的pointer-events属性详细介绍(作用和注意事项)
2014/04/23 HTML / CSS
Falconeri美国官网:由羊绒和羊毛制成的针织服装
2018/04/08 全球购物
吉列剃须刀美国官网:Gillette美国
2018/07/13 全球购物
学生安全责任书
2014/04/15 职场文书
答谢会策划方案
2014/05/12 职场文书
优秀学生党员先进事迹材料
2014/05/29 职场文书
保护动物的标语
2014/06/11 职场文书
材料化学专业求职信
2014/07/15 职场文书
医院护士党的群众路线教育实践活动对照检查材料思想汇报
2014/10/04 职场文书
深入理解go slice结构
2021/09/15 Golang