详解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 相关文章推荐
贴一个在Mozilla中常用的Javascript代码
Jan 09 Javascript
jQuery表单验证插件formValidator(改进版)
Feb 03 Javascript
A标签中通过href和onclick传递的this对象实现思路
Apr 19 Javascript
javascript通过navigator.userAgent识别各种浏览器
Oct 25 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
Nov 19 Javascript
jQuery中Ajax的load方法详解
Jan 14 Javascript
jQuery实现定时读取分析xml文件的方法
Jul 16 Javascript
使用HTML+CSS+JS制作简单的网页菜单界面
Jul 27 Javascript
jQuery ztree实现动态树形多选菜单
Aug 12 Javascript
jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法
Dec 24 Javascript
简单实现js上传文件功能
Aug 21 Javascript
Vue自定义指令封装节流函数的方法示例
Jul 09 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
php中的一些数组排序方法分享
2012/07/20 PHP
PHP简单的MVC框架实现方法
2015/12/01 PHP
JavaScript对象链式操作代码(jquery)
2010/07/04 Javascript
jquery和ajax的关系详细介绍
2013/11/29 Javascript
jQuery函数map()和each()介绍及异同点分析
2014/11/08 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
详解JS构造函数中this和return
2017/09/16 Javascript
vue基于Element构建自定义树的示例代码
2017/09/19 Javascript
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
2017/09/20 jQuery
React中常见的动画实现的几种方式
2018/01/10 Javascript
解决bootstrap-select 动态加载数据不显示的问题
2018/08/10 Javascript
js实现简单选项卡功能
2020/03/23 Javascript
vue中使用微信公众号js-sdk踩坑记录
2019/03/29 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
2020/07/21 Javascript
跟老齐学Python之字典,你还记得吗?
2014/09/20 Python
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
在Python中使用成员运算符的示例
2015/05/13 Python
Python函数式编程指南(二):从函数开始
2015/06/24 Python
详解Python编程中包的概念与管理
2015/10/16 Python
使用Python读取大文件的方法
2018/02/11 Python
Python操作Oracle数据库的简单方法和封装类实例
2018/05/07 Python
对python3中pathlib库的Path类的使用详解
2018/10/14 Python
Pycharm+Scrapy安装并且初始化项目的方法
2019/01/15 Python
python爬虫爬取微博评论案例详解
2019/03/27 Python
opencv 图像轮廓的实现示例
2020/07/08 Python
详解background属性的8个属性值(面试题)
2020/11/02 HTML / CSS
挪威太阳镜和眼镜网上商城:SmartBuyGlasses挪威
2016/08/20 全球购物
ETO男装官方网店:ETO Jeans
2019/02/28 全球购物
澳大利亚最受欢迎的美发用品目的地:AMR
2019/08/28 全球购物
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
开办大学饮食联盟创业计划书
2014/01/29 职场文书
行政人事专员岗位职责
2014/03/05 职场文书
英语通知范文
2015/04/22 职场文书
Redis keys命令的具体使用
2022/06/05 Redis
3050和2060哪个好 性能差多少 差距有多大 谁更有性价比
2022/06/17 数码科技