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 相关文章推荐
js验证表单第二部分
Nov 25 Javascript
一些实用的jQuery代码片段收集
Jul 12 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
Oct 11 Javascript
关于Javascript与iframe的那些事儿
Jul 04 Javascript
jQuery实现折线图的方法
Feb 28 Javascript
JavaScript中的toUTCString()方法使用详解
Jun 12 Javascript
jQuery中选择器的基础使用教程
May 23 Javascript
jquery与ajax获取特殊字符实例详解
Jan 08 Javascript
基于Vue2x的图片预览插件的示例代码
May 14 Javascript
JavaScript错误处理操作实例详解
Jan 04 Javascript
Vue 实现分页与输入框关键字筛选功能
Jan 02 Javascript
vue-cli4.0多环境配置变量与模式详解
Dec 30 Vue.js
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
提高define性能的php扩展hidef的安装和使用
2011/06/14 PHP
php实现监控varnish缓存服务器的状态
2014/12/30 PHP
PHP函数checkdnsrr用法详解(Windows平台用法)
2016/03/21 PHP
PHP is_array() 检测变量是否是数组的实现方法
2016/06/13 PHP
thinkphp 验证码 的使用小结
2017/05/07 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
2018/05/12 PHP
js对字符的验证方法汇总
2015/02/04 Javascript
JavaScript中exec函数用法实例分析
2015/06/08 Javascript
ES6的新特性概览
2016/03/10 Javascript
使用JavaScriptCore实现OC和JS交互详解
2017/03/28 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(上)
2017/04/21 Javascript
JS使用正则表达式找出最长连续子串长度
2017/10/26 Javascript
angularjs实现柱状图动态加载的示例
2017/12/11 Javascript
微信小程序云开发实现数据添加、查询和分页
2019/05/17 Javascript
vue组件库的在线主题编辑器的实现思路
2020/04/03 Javascript
Vue向后台传数组数据,springboot接收vue传的数组数据实例
2020/11/12 Javascript
[05:35]DOTA2英雄梦之声_第13期_拉比克
2014/06/21 DOTA
Python socket编程实例详解
2015/05/27 Python
Python爬虫辅助利器PyQuery模块的安装使用攻略
2016/04/24 Python
Python简单实现查找一个字符串中最长不重复子串的方法
2018/03/26 Python
Django Admin中增加导出CSV功能过程解析
2019/09/04 Python
使用PyQt5实现图片查看器的示例代码
2020/04/21 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
Python使用shutil模块实现文件拷贝
2020/07/31 Python
python闭包与引用以及需要注意的陷阱
2020/09/18 Python
MoviePy常用剪辑类及Python视频剪辑自动化
2020/12/18 Python
Python 爬虫批量爬取网页图片保存到本地的实现代码
2020/12/24 Python
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
如何用Java判断一个文件或目录是否存在
2012/11/19 面试题
J2EE系统只能是基于web
2015/09/08 面试题
优秀生推荐信范文
2013/11/28 职场文书
施工安全承诺书
2014/05/22 职场文书
2015年六一儿童节活动总结
2015/02/11 职场文书
工作岗位职责范本
2015/02/15 职场文书
风雨哈佛路观后感
2015/06/03 职场文书
机关单位2016年法制宣传日活动总结
2016/04/01 职场文书