Directive之间互相通讯

本节是Directive的高级使用方法之一,通过赋予Directive之间互相通讯的功能,我们可以将部件的抽象化提升到一个更高的层次。

本节将通过官方网站中一个较复杂的例子来讲解具体的使用方法,通过Directive的配置,将HTML中的代码自动抽取为一个Tab列表,点击Tab列表中的标题,则可自动的显示Tab中包含的内容。

在JavaScript代码中,我们声明了2个Directive,gqTabContainergqTabContent

gqTabContainer中加入了controller这项配置,并封装了panes用于存储数据,$scope.select用于接收界面点击事件,以及一个addPane方法用于接收gqTabContent的调用。

gqTabContent中加入了require这项配置,获取的对象作为第四个参数传入link()函数。

  1. var App = angular.module("App", []);
  2. App.directive("gqTabContainer", function () {
  3. return {
  4. restrict: 'E',
  5. transclude: true,
  6. scope: {},
  7. //注意这里为tabContainer增加了一个controller,并引入了$scope
  8. controller: ['$scope', function ($scope) {
  9. var panes = $scope.panes = [];
  10. //tab列表中项目被选中(点击)的处理函数
  11. $scope.select = function (pane) {
  12. angular.forEach(panes, function (pane) {
  13. pane.selected = false;
  14. });
  15. pane.selected = true;
  16. };
  17. //初始化页面时,供其他Directive调用的注册函数
  18. this.addPane = function (pane) {
  19. if (panes.length === 0) {
  20. $scope.select(pane);
  21. }
  22. panes.push(pane);
  23. };
  24. }],
  25. //注意templateUrl的命名
  26. templateUrl: "gqTabList"
  27. };
  28. });
  29. App.directive('gqTabContent', function () {
  30. return {
  31. //获取gqTabContainer这个Directive
  32. require: '^gqTabContainer',
  33. restrict: 'E',
  34. transclude: true,
  35. scope: {
  36. title: '@'
  37. },
  38. //第四个参数是获取到的Directive
  39. link: function (scope, element, attrs, tabContainer) {
  40. //调用了上方gqTabContainer的addPane()方法
  41. //注意参数命名,不需要和上方Directive一致
  42. tabContainer.addPane(scope);
  43. },
  44. //注意templateUrl的命名
  45. templateUrl: "gqTabContent"
  46. };
  47. });

在HTML代码中,我们直接使用了gq-tab-containergq-tab-content

  1. <!DOCTYPE html>
  2. <html lang="zh" ng-app="App">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>{{"学习AngularJS 1.x"}}</title>
  6. <link href="css/style.css" rel="stylesheet">
  7. </head>
  8. <body>
  9. <script type="text/javascript" src="components/jquery/dist/jquery.js"></script>
  10. <script type="text/javascript" src="components/angular/angular.js"></script>
  11. <script type="text/javascript" src="js/app.js"></script>
  12. <gq-tab-container>
  13. <gq-tab-content title="标签1">
  14. <h4>标题1</h4>
  15. <p>这是第一个标签下的内容</p>
  16. </gq-tab-content>
  17. <gq-tab-content title="标签2">
  18. <h4>标题2</h4>
  19. <p>这是第二个标签下的内容</p>
  20. </gq-tab-content>
  21. </gq-tab-container>
  22. <!--这里为了将文件整理在一起,使用了ng-template的方式-->
  23. <script type="text/ng-template" id="gqTabList">
  24. <ul>
  25. <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
  26. <a href="" ng-click="select(pane)">{{pane.title}}</a>
  27. </li>
  28. </ul>
  29. <div ng-transclude></div>
  30. </script>
  31. <script type="text/ng-template" id="gqTabContent">
  32. <div ng-show="selected" ng-transclude>
  33. </div>
  34. </script>
  35. </body>
  36. </html>

运行效果:

  • 当点击”标签1”或”标签2”时,下方会自动展示对应的内容。

    图5-16 Directive之间通讯