详解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 相关文章推荐
Hutia 的 JS 代码集
Oct 24 Javascript
javascript Zifa FormValid 0.1表单验证 代码打包下载
Jun 08 Javascript
jQuery中clone()方法用法实例
Jan 16 Javascript
Bootstrap教程JS插件弹出框学习笔记分享
May 17 Javascript
Javascript中的数组常用方法解析
Jun 17 Javascript
JavaScrpt判断一个数是否是质数的实例代码
Jun 11 Javascript
vue深入解析之render function code详解
Jul 18 Javascript
浅析Vue自定义组件的v-model
Nov 26 Javascript
详解Vue结合后台的列表增删改案例
Aug 21 Javascript
jquery拖拽自动排序插件使用方法详解
Jul 20 jQuery
详解vue项目中使用token的身份验证的简单实践
Mar 08 Javascript
微信小程序实现授权登录
May 15 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
sphinx增量索引的一个问题
2011/06/14 PHP
php 根据url自动生成缩略图并处理高并发问题
2014/01/23 PHP
php 获取页面中指定内容的实现类
2014/01/23 PHP
PHP中的事务使用实例
2015/05/26 PHP
以实例全面讲解PHP中多进程编程的相关函数的使用
2015/08/18 PHP
日常整理PHP中简单的图形处理(经典)
2015/10/26 PHP
jQuery层级选择器用法分析
2015/02/10 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
2015/06/05 Javascript
nodejs创建web服务器之hello world程序
2015/08/20 NodeJs
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
webpack入门必知必会
2017/01/16 Javascript
ajax与json 获取数据并在前台使用简单实例
2017/01/19 Javascript
JavaScript用200行代码制作打飞机小游戏实例
2017/06/21 Javascript
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
2017/09/05 Javascript
微信小程序支付前端源码
2018/08/29 Javascript
Vue.js 十五分钟入门图文教程
2018/09/12 Javascript
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
2019/02/20 jQuery
使用Node.js实现一个多人游戏服务器引擎
2019/03/13 Javascript
vue-autoui自匹配webapi的UI控件的实现
2020/03/20 Javascript
JavaScript进阶(一)变量声明提升实例分析
2020/05/09 Javascript
js数组的基本使用总结
2021/01/18 Javascript
python以环状形式组合排列图片并输出的方法
2015/03/17 Python
Python中规范定义命名空间的一些建议
2016/06/04 Python
Python处理文本换行符实例代码
2018/02/03 Python
Python操作word常见方法示例【win32com与docx模块】
2018/07/17 Python
Python修改文件往指定行插入内容的实例
2019/01/30 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
Python tkinter 下拉日历控件代码
2020/03/04 Python
python定义类的简单用法
2020/07/24 Python
Noon埃及:埃及在线购物
2019/11/26 全球购物
店长岗位的工作内容
2013/11/12 职场文书
超市周年庆活动方案
2014/08/16 职场文书
家庭贫困证明书(3篇)
2014/09/15 职场文书
学校领导干部民主生活会整改方案
2014/09/29 职场文书
铁人观后感
2015/06/16 职场文书