详解angular 中的自定义指令之详解API


Posted in Javascript onJune 20, 2017

自定义属性的四种类别

分为: 元素E,属性A,注释M,类C , 分别如下:

<my-dir></my-dir>
 <span my-dir="exp"></span>
 <!-- directive: my-dir exp -->
 <span class="my-dir: exp;"></span>

简单创建一个指令

html结构:

<div ng-controller="myCtrl">
 <div my-customer></div>
</div>

JavaScript结构:

angular.module('myApp', [])
  .controller('myCtrl', ['$scope', function($scope) {
   $scope.customer = {
    name: 'Naomi',
    address: '1600 Amphitheatre'
   };
  }])
  .directive('myCustomer', function() {
   return {
    template: 'Name: {{customer.name}} Address: {{customer.address}}'
   };
  });

输出:

Name: Naomi Address: 1600 Amphitheatre

说明: 此处,myCtrl 中定义的 $scope.customer 属性和属性值都在指令中的模板使用了。同样的,在指令return 对象中的 template 也可被替换成一路径,在路径html中书写和template中同样的代码,使用这种方式,可以操作更多代码。

templateUrl 函数式编程

html结构:

<div ng-controller="myCtrl">
  <div my-customer></div>
</div>

javascript结构:

angular.module('myApp', [])
 .controller('myCtrl', ['$scope', function($scope) {
  $scope.customer = {
   name: 'Naomi',
   address: '1600 Amphitheatre'
  };
   }])
 .directive('myCustomer', function() {
  return {
   templateUrl: function(elem, attr) {
    return 'customer-' + attr.type + '.html';
   }
  };
 });

不同的templateUrl ①

Name: {{customer.name}}

不同的templateUrl ②

Address: {{customer.address}}

输出结果:

Name: Naomi
Address: 1600 Amphitheatre

说明: templateUrl 的值可以是一个函数返回值,返回用于指令中的html模板的url。

隔离指令的作用域

① 通过不同的controller

html结构:

<div ng-app="myApp">
  <div ng-controller="myCtrl1">
    <my-customer></my-customer>
  </div>
  <div ng-controller="myCtrl2">
    <my-customer></my-customer>
  </div>
</div>

javascript结构:

angular.module('myApp', [])
  .controller('myCtrl1', ['$scope', function($scope) {
   $scope.customer = {
    name: 'Naomi',
    address: '1600 Amphitheatre'
   };
  }])
  .controller('myCtrl2', ['$scope', function($scope) {
   $scope.customer = {
    name: 'Igor',
    address: '123 Somewhere'
   };
  }])
  .directive('myCustomer', function() {
   return {
    restrict: 'E',
    templateUrl: 'my-customer.html'
   };
  });

templateUrl html 结构:

Name: {{customer.name}} Address: {{customer.address}}

输出结果:

 Name: Naomi Address: 1600 Amphitheatre
 Name: Igor Address: 123 Somewhere

说明: 可见 不同的controller 有不同的作用范围。虽然指令一样,每次渲染都是分离的,所以我们可以抽象出来指令,用于html模板和代码的重用,封装。但是这样又不是很好,因为用了两个controller,我们可以使用指令中的scope而不是controller里的scope来替代,具体做法是将外部的scope 映射到指令内部的scope, 如下:

② 通过指令属性映射scope

html结构:

<div ng-app="myApp" ng-controller="myCtrl">
 <my-customer info="naomi"></my-customer>
 <my-customer info="igor"></my-customer>
</div>

javascript 结构:

angular.module('myApp', [])
  .controller('myCtrl', ['$scope', function($scope) {
   $scope.naomi = { name: 'Naomi', address: '1600 Amphitheatre' };
   $scope.igor = { name: 'Igor', address: '123 Somewhere' };
  }])
  .directive('myCustomer', function() {
   return {
    restrict: 'E',
    scope: {
     customerInfo: '=info'
    },
    templateUrl: 'my-customer-iso.html'
   };
  });

templateUrl html结构:

Name: {{customerInfo.name}} Address: {{customerInfo.address}}

编译后的html结果:

 Name: Naomi Address: 1600 Amphitheatre
 Name: Igor Address: 123 Somewhere

③ 指令中的如果定义scope属性则html中的scope不会直接继承controller中的scope,在html中使用的都需要在scope:{}中声明,否则就是undefined

html 结构:

<div ng-app="myApp" ng-controller="myCtrl">
   <my-customer info="naomi"></my-customer>
 </div>

javascript结构:

angular.module('myApp', [])
  .controller('myCtrl', ['$scope', function($scope) {
   $scope.naomi = { name: 'Naomi', address: '1600 Amphitheatre' };
   $scope.vojta = { name: 'Vojta', address: '3456 Somewhere Else' };
  }])
  .directive('myCustomer', function() {
   return {
    restrict: 'E',
    scope: {
     customerInfo: '=info'
    },
    templateUrl: 'my-customer-plus-vojta.html'
   };
  });

  templateUrl html结构:

Name: {{customerInfo.name}} Address: {{customerInfo.address}}
<br>
Name: {{vojta.name}} Address: {{vojta.address}}

html编译后的结果:

Name: Naomi Address: 1600 Amphitheatre
Name: Address:

说明: vojta 在指令中的scope没有被定义,不会直接继承在controller中的,那么他就是undefined,所以就是空白(什么都不显示)

可操作DOM的指令

创建一个用于操作dom的指令,如果需要dom操作也都应该放在指令里。

html 结构:

<div ng-app="myApp" ng-controller="myCtrl">
  Date format: <input ng-model="format"> <hr/>
  Current time is: <span my-current-time="format"></span>
 </div>

javascript结构:

angular.module('myApp', [])
  .controller('myCtrl', ['$scope', function($scope) {
    $scope.format = 'M/d/yy h:mm:ss a';
  }])
  .directive('myCurrentTime', function($interval, dateFilter) {
    return {
     restrict: 'AE',
     link: function(scope, element, attr){
       var format, timeoutId;

      /* 更新时间函数 */
      function updateTime() {
       element.text(dateFilter(new Date(), format));
      }

      /* 监视时间格式的改变 */
      var attrWatch = scope.$watch(attrs.myCurrentTime, function(value) {
       format = value;
       updateTime();
      });

      /* 定时器 */
      timeoutId = $interval(function() {
       updateTime(); // update DOM
      }, 1000);

      /* 页面跳转后移除定时器防止内存泄露 */
      element.on('$destroy', function() {
       $interval.cancel(timeoutId);
       attrWatch(); // 移除watch
      });
    }
   };
  });

说明: 在link函数中,操作dom节点,让dom的文本节点动态显示时间跳动。在页面跳转之后及时清除定时器和监视器以免发生内存泄漏。

通过transclude和ng-transclude创建可包裹其他元素的指令

html结构:

<div ng-app="myApp" ng-controller="myCtrl">
   <my-dialog>Check out the contents, {{name}}!</my-dialog>
 </div>

javascript结构:

angular.module('myApp', [])
  .controller('myCtrl', ['$scope', function($scope) {
    $scope.name = 'Tobias';
  }])
  .directive('myDialog', function() {
   return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
 };
});

templateUrl html 结构:

<div class="alert" ng-transclude></div>

编译后的html结构:

Check out the contents, Tobias!

说明: 指令中的scope本应隔离controller中的作用域的,但是由于设置了transclude=true选项,scope就会继承controller中的定义,所以最终是Tobias而不是Jeff。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 颜色选择器(兼容firefox)
Mar 05 Javascript
javascript alert乱码的解决方法
Nov 05 Javascript
详解AngularJs HTTP响应拦截器实现登陆、权限校验
Apr 11 Javascript
[js高手之路]HTML标签解释成DOM节点的实现方法
Aug 31 Javascript
使用Vue.js开发微信小程序开源框架mpvue解析
Mar 20 Javascript
微信小程序实现之手势锁功能实例代码
Jul 19 Javascript
Vue.js获取被选择的option的value和text值方法
Aug 24 Javascript
angularJs在多个控制器中共享服务数据的方法
Sep 30 Javascript
jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法分析
Mar 06 jQuery
JS浏览器BOM常见操作实例详解
Apr 27 Javascript
vue开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 Vue.js
使用react-virtualized实现图片动态高度长列表的问题
May 28 Javascript
JS移动端/H5同时选择多张图片上传并使用canvas压缩图片
Jun 20 #Javascript
BootStrap Select清除选中的状态恢复默认状态
Jun 20 #Javascript
Vue实现路由跳转和嵌套
Jun 20 #Javascript
Vue.2.0.5实现Class 与 Style 绑定的实例
Jun 20 #Javascript
JS中的三个循环小结
Jun 20 #Javascript
详解Vue 方法与事件处理器
Jun 20 #Javascript
Vue Ajax跨域请求实例详解
Jun 20 #Javascript
You might like
音乐朗读剧《MARS RED》2021年TV动画化决定!
2020/03/06 日漫
PHP数组的交集array_intersect(),array_intersect_assoc(),array_inter_key()函数的小问题
2011/05/29 PHP
深入PHP内存相关的功能特性详解
2013/06/08 PHP
easyui的tabs update正确用法分享
2014/03/21 PHP
php 魔术常量详解及实例代码
2016/12/04 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
Laravel学习教程之View模块详解
2017/09/18 PHP
Laravel框架FormRequest中重写错误处理的方法
2019/02/18 PHP
浅谈JavaScript中面向对象技术的模拟
2006/09/25 Javascript
用jquery写的一个万年历(自写)
2014/01/20 Javascript
Javascript实现的常用算法(如冒泡、快速、鸽巢、奇偶等)
2014/04/29 Javascript
JavaScript检查某个function是否是原生代码的方法
2014/08/20 Javascript
javascript实现复制与粘贴操作实例
2014/10/16 Javascript
JavaScript基础知识及常用方法总结
2016/01/10 Javascript
JS实现的简单轮播图运动效果示例
2016/12/22 Javascript
NodeJS遍历文件生产文件列表功能示例
2017/01/22 NodeJs
利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
2017/11/20 Javascript
Vue入门之数据绑定(小结)
2018/01/08 Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
2019/04/23 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
2019/09/10 jQuery
[01:11:21]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第三场 3月7日
2021/03/11 DOTA
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
python虚拟环境的安装配置图文教程
2017/10/20 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
Django实现微信小程序的登录验证功能并维护登录态
2019/07/04 Python
Win10环境python3.7安装dlib模块趟过的坑
2019/08/01 Python
python conda操作方法
2019/09/11 Python
Python selenium模拟手动操作实现无人值守刷积分功能
2020/05/13 Python
Python获取指定网段正在使用的IP
2020/12/14 Python
Python 中的函数装饰器和闭包详解
2021/02/06 Python
Html5剪切板功能的实现代码
2018/06/29 HTML / CSS
英国电动工具购买网站:Anglia Tool Centre
2017/04/25 全球购物
Juicy Couture Beauty官方网站:香水和化妆品
2019/03/12 全球购物
师范生自我鉴定
2014/03/20 职场文书
python删除csv文件的行列
2021/04/06 Python
Redis高级数据类型Hyperloglog、Bitmap的使用
2021/05/24 Redis