表的Angular指令作为父级,theader和tbody作为子级

时间:2016-01-20 19:20:07

标签: angularjs angularjs-directive

我正在尝试使用2个子指令执行父指令。 这样做的主要原因是强制应用程序中的所有表使用相同的“模板”。

我的问题是我需要在指令中复制Dom。 所以我的主要指令是table指令,frist子节点是thead,第二个子节点是tbody。

这是标记

<div my-table >
  <my-thead>
      <tr>
          <th ng-click="alert('Id')"> Id </th>
          <th ng-click="alert('Name')"> Name </th>
      </tr>
  </my-thead>
  <my-tbody>
      <tr ng-repeat ="item in List">
          <td>{{item.Id}}</td>
          <td>{{item.Name}}</td>
      </tr>
  </my-tbody>
</div>

指令my-table将生成表结构所需的所有代码,而dir my-thead和my-tbody将创建标签thead和tbody并让它们做父div。 我的问题仍然是复制my-thead和my-tbody的内部标记,因为它们是tr,有什么建议吗?

接下来,我将向您展示我到目前为止最新的代码

myTable的

angular
.module('App')
.directive('myTable', ['$compile',
  function($compile){
    var tableSettings = {};
      return {
        restriction :'AE',
        scope : {},
        replace : false,
        link : function(scope,element){
        var divContainerFluid = angular.element('<div>');
        var divRowTable = angular.element('<div>');
        var divColTable = angular.element('<div>');

        divContainerFluid.addClass('container-fluid');
        divRowTable.addClass('Row');
        divColTable.addClass('col-lg-12');

        var divTable = angular.element('<div>');
        var table = angular.element('<table>');

        table.addClass('table');
        table.addClass('table-striped');

        //add from thead
        table.append(tableSettings.tHead);
        //add from tbody
        table.append(tableSettings.tBody);

        divTable.append(table);

        divColTable.append(divTable);

        divRowTable.append(divColTable);

        divContainerFluid.append(divRowTable);

        $compile(divContainerFluid)(scope);

        element.append(divContainerFluid);
      },
      controller: function () {

        this.receiveTHead = function (tHead) {
          tableSettings.tHead = tHead;
        }

        this.receiveTBody = function (tBody) {
          tableSettings.tBody = tBody;
        }
      }
    }
 }]);

myHead

angular
.module('App')
.directive('myThead', [
  function() {
    return {
      restriction: "E",
      scope: true,
      require: "^myTable",
      replace: true,
      transclude: true,
      template:'<thead class="form-class" ng-cloak>' +
               '</thead>',
      link: function(scope, element, attrs, myTableCtrl, transclude)
      {
        transclude(function(clone){
          element.append(clone);
        });
        myTableCtrl
          .receiveTHead(element);
      }
    };
  }
]);

myBody

angular
.module('App')
.directive('myThead', [
  function() {
    return {
      restriction: "E",
      scope: true,
      require: "^myTable",
      replace: true,
      transclude: true,
      template:'<thead class="form-class" ng-cloak>' +
               '</thead>',
      link: function(scope, element, attrs, myTableCtrl, transclude)
      {
        transclude(function(clone){
          element.append(clone);
        });
        myTableCtrl
          .receiveTHead(element);
      }
    };
  }
]);

Plunker

谢谢你的帮助。

更新

缺少listCtrl

angular.module('App',[])
.controller('listCtrl',['$scope','$timeout',
  function($scope,$timeout){
    $timeout(function () {
      $scope.List = [ {Id : '1', Name : 'Name1'}, {Id : '2', Name :'Name2'}];
    }, 1500);
  }
]);

更新

我从不同的角度重新创建了这个问题。但是身体没有填充scope.List中的信息,任何想法?

<div my-table>
<table>
    <thead>
        <tr>
            <th ng-click="resort('Id')"> Id </th>
            <th ng-click="resort('Name')"> Name </th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="user in List">
            <td>{{user.Id}}</td>
            <td>{{user.Name}}</td>
        </tr>
    </tbody>
</table>
</div>

myTable的

angular
.module('App')
.directive('myTable', [
    '$compile',
    function($compile) {
        return {
            restriction: 'AE',
            //scope: {
            //    plEmptytext: '@'
            //},
            transclude: true,
            template:
                '<div class="container-fluid">' +
                    '<div class="row">' +
                    '<div class="col-lg-12">' +
                    '<div ng-transclude></div>' +
                    '</div>' +
                    '</div>' +
                    '</div>',
            link: function(scope, element) {

                var table = element.find('table');

                table.addClass('table');
                table.addClass('table-striped');

                var tHead = element.find('thead');

                var tBody = element.find('tbody');
                tBody.attr('ng-controller', 'listCtrl');

                $compile(tHead)(scope);
                $compile(tBody)(scope);
                $compile(table)(scope);

            }
        };
    }
]);

listCtrl是相同的

Plunker 2

SOLUTION:

对于那些可能来到这里的人,我的解决方案必须添加到指令tBody return{ controller: 'listCtrl' ...

3 个答案:

答案 0 :(得分:1)

可能仍然提供所需的“一个模板适用于所有”目标的另一种方法是编写html模板文件,并在声明ng-include时使用表时引用它。与旧的服务器端包含类似,它提供了一种方法,可以随时随地注入一个html块,而无需指令的所有开销。

我们实际上已经退出了制定如此多的指令,并且当指令中没有任何工作要做时,我们开始使用包括更多指令。

Angular documentation on ngInclude

答案 1 :(得分:0)

听起来你需要“多插槽翻转”。

这在角度版本中可用&gt; 1.5 https://docs.angularjs.org/api/ng/directive/ngTransclude

答案 2 :(得分:0)

对于可能来到这里的人,我的解决方案必须添加到指令tBody

return{ controller: 'listCtrl' ...

对我而言,这是我一直在寻找的解决方案。