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

自定义属性的四种类别

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

rush:xhtml;">

简单创建一个指令

html结构:

rush:xhtml;">

JavaScript结构:

rush:js;"> 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}}' }; });

输出

rush:plain;"> Name: Naomi Address: 1600 Amphitheatre

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

templateUrl 函数式编程

html结构:

rush:xhtml;">

javascript结构:

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

不同的templateUrl ①

rush:js;"> Name: {{customer.name}}

不同的templateUrl ②

rush:js;"> Address: {{customer.address}}

输出结果:

Name: Naomi Address: 1600 Amphitheatre

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

隔离指令的作用域

① 通过不同的controller

html结构:

rush:xhtml;">

javascript结构:

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

templateUrl html 结构:

rush:js;"> 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结构:

rush:xhtml;">

javascript 结构:

rush:js;"> angular.module('myApp',function($scope) { $scope.naomi = { name: 'Naomi',address: '1600 Amphitheatre' }; $scope.igor = { name: 'Igor',address: '123 Somewhere' }; }]) .directive('myCustomer',scope: { customerInfo: '=info' },templateUrl: 'my-customer-iso.html' }; });

templateUrl html结构:

rush:js;"> 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 结构:

rush:xhtml;">

javascript结构:

rush:js;"> angular.module('myApp',address: '1600 Amphitheatre' }; $scope.vojta = { name: 'Vojta',address: '3456 Somewhere Else' }; }]) .directive('myCustomer',templateUrl: 'my-customer-plus-vojta.html' }; });

templateUrl html结构:

rush:xhtml;"> Name: {{customerInfo.name}} Address: {{customerInfo.address}}
Name: {{vojta.name}} Address: {{vojta.address}}

html编译后的结果:

Name: Naomi Address: 1600 Amphitheatre Name: Address:

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

可操作DOM的指令

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

html 结构:

rush:xhtml;">
Current time is:

javascript结构:

rush:js;"> angular.module('myApp',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;
  /* 更新<a href="https://www.jb51.cc/tag/shijianhan/" target="_blank" class="keywords">时间函</a>数 */
  function updateTime() {
   element.text(<a href="https://www.jb51.cc/tag/datefilter/" target="_blank" class="keywords">datefilter</a>(new Date(),format));
  }

  /* 监视时间格式的改变 */
  var attrWatch = s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.$watch(attrs.myCurrentTime,function(value) {
   format = value;
   updateTime();
  });

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

  /* <a href="https://www.jb51.cc/tag/yemian/" target="_blank" class="keywords">页面</a><a href="https://www.jb51.cc/tag/tiaozhuan/" target="_blank" class="keywords">跳转</a>后移除定时器防止内存泄露 */
  element.on('$destroy',function() {
   $interval.cancel(timeoutId);
   attrWatch(); // 移除watch
  });
}

};
});

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

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

html结构:

rush:xhtml;">
Check out the contents,{{name}}!

javascript结构:

rush:js;"> angular.module('myApp',function($scope) { $scope.name = 'Tobias'; }]) .directive('myDialog',transclude: true,scope: {},templateUrl: 'my-dialog.html',link: function(scope) { scope.name = 'Jeff'; } }; });

templateUrl html 结构:

rush:xhtml;">

编译后的html结构:

Check out the contents,Tobias!

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

相关文章

什么是深拷贝与浅拷贝?深拷贝与浅拷贝是js中处理对象或数据...
前言 今天复习了一些前端算法题,写到一两道比较有意思的题:...
最近在看回JavaScript的面试题,this 指向问题是入坑前端必须...
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面