加载中...

基本的自定义方法


18.3. 基本的自定义方法

自定义一个指令可以非常非常的复杂,但是其基本的调用形式,同自定义服务大概是相同的:

  1. <p show style="font-size: 12px;"></p>
  2. <script type="text/javascript">
  3. var app = angular.module('Demo', [], angular.noop);
  4. app.directive('show', function(){
  5. var func = function($scope, $element, $attrs){
  6. console.log($scope);
  7. console.log($element);
  8. console.log($attrs);
  9. } return func;
  10. //return {compile: function(){return func}}
  11. });
  12. angular.bootstrap(document, ['Demo']);
  13. </script>

如果在 directive 中直接返回一个函数,则这个函数会作为 compile 的返回值,也即是作为 link 函数使用。这里说的 compilelink 都是一个指令的组成部分,一个完整的定义应该返回一个对象,这个对象包括了多个属性:

  • name
  • priority
  • terminal
  • scope
  • controller
  • require
  • restrict
  • template
  • templateUrl
  • replace
  • transclude
  • compile
  • link

上面的每一个属性,都可以单独探讨的。

下面是一个完整的基本的指令定义例子:

  1. <code lines>
  2. //失去焦点使用 jQuery 的扩展支持冒泡
  3. app.directive('ngBlur', function($parse){
  4. return function($scope, $element, $attr){
  5. var fn = $parse($attr['ngBlur']);
  6. $element.on('focusout', function(event){
  7. fn($scope, {$event: event});
  8. });
  9. }
  10. });
  11. </code>
  12. <div code lines>
  13. //失去焦点使用 jQuery 的扩展支持冒泡
  14. app.directive('ngBlur', function($parse){
  15. return function($scope, $element, $attr){
  16. var fn = $parse($attr['ngBlur']);
  17. $element.on('focusout', function(event){
  18. fn($scope, {$event: event});
  19. });
  20. }
  21. });
  22. </div>
  23. 1 var app = angular.module('Demo', [], angular.noop);
  24. 2 3 app.directive('code', function(){
  25. 4 var func = function($scope, $element, $attrs){
  26. 5 6 var html = $element.text();
  27. 7 var lines = html.split('\n');
  28. 8 9 //处理首尾空白
  29. 10 if(lines[0] == ''){lines = lines.slice(1, lines.length - 1)}
  30. 11 if(lines[lines.length-1] == ''){lines = lines.slice(0, lines.length - 1)}
  31. 1213 $element.empty();
  32. 1415 //处理外框
  33. 16 (function(){
  34. 17 $element.css('clear', 'both');
  35. 18 $element.css('display', 'block');
  36. 19 $element.css('line-height', '20px');
  37. 20 $element.css('height', '200px');
  38. 21 })();
  39. 2223 //是否显示行号的选项
  40. 24 if('lines' in $attrs){
  41. 25 //处理行号
  42. 26 (function(){
  43. 27 var div = $('<div style="width: %spx; background-color: gray; float: left; text-align: right; padding-right: 5px; margin-right: 10px;"></div>'
  44. 28 .replace('%s', String(lines.length).length * 10));
  45. 29 var s = '';
  46. 30 angular.forEach(lines, function(_, i){
  47. 31 s += '<pre style="margin: 0;">%s</pre>\n'.replace('%s', i + 1);
  48. 32 });
  49. 33 div.html(s);
  50. 34 $element.append(div);
  51. 35 })();
  52. 36 }
  53. 3738 //处理内容
  54. 39 (function(){
  55. 40 var div = $('<div style="float: left;"></div>');
  56. 41 var s = '';
  57. 42 angular.forEach(lines, function(l){
  58. 43 s += '<span style="margin: 0;">%s</span><br />\n'.replace('%s', l.replace(/\s/g, '<span>&nbsp;</span>'));
  59. 44 });
  60. 45 div.html(s);
  61. 46 $element.append(div);
  62. 47 })();
  63. 48 }
  64. 4950 return {link: func,
  65. 51 restrict: 'AE'}; //以元素或属性的形式使用命令
  66. 52 });
  67. 5354 angular.bootstrap(document, ['Demo']);

上面这个自定义的指令,做的事情就是解析节点中的文本内容,然后修改它,再把生成的新内容填充到节点当中去。其间还涉及了节点属性值 lines 的处理。这算是指令中最简单的一种形式。因为它是“一次性使用”,中间没有变量的处理。比如如果节点原来的文本内容是一个变量引用,类似于 {{ code }} ,那上面的代码就不行了。这种情况麻烦得多。后面会讨论。


还没有评论.