生成带插值和转换的表

时间:2014-02-11 01:20:16

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我正在尝试使用AngularJS中的指令和tansclude组合一个可重用但自定义的表类型控件,并且我遇到了无法使用{{语法自定义进入表列的内容的问题。 }}

我尝试了很多不同的版本但却无法使其正常工作。我会包含代码,但我不认为我在正确的轨道上?

我想要实现的目标:

数据:

mymodel.items = [{ number: 1, name: 'John'}, {number: 2, name: 'Bob'}]

HTML:

<grid items="mymodel.items">
    <column title="#">#{{item.number}}</column>
    <column title="Name"><b>Hello {{item.name}}</b></column>
</grid>

模板:

<table>
    <thead>
        <th ng-repeat="column in columns">{{column.title}}</th>
    </thead>
    <tbody>
        <tr ng-repeat="item in items">
             <td ng-repeat="column in columns">{{columnValue(item, column.content)}}</th>
        </tr>
    </tbody>
</table>

预期产出:

<table>
    <thead>
        <th>#</th>
        <th>Name</th>
    </thead>
    <tbody>
        <tr>
            <td>#1</td>
            <td>Hello John</td>
        </tr>
        <tr>
            <td>#2</td>
            <td>Hello Bob</td>
        </tr>
    </tbody>
</table>

我似乎无法弄清楚如何在“网格”中转换内容,以便可以进行插值。

1 个答案:

答案 0 :(得分:6)

您可以手动创建模板:

这是一个掠夺者:http://plnkr.co/edit/C7HTRYZ4Hs1uOC9PXuza?p=preview

app.directive('grid', function() {
  return {
    restrict: 'E',
    replace:true,
    scope: {
      items: "="
    },
    template: function(tElm, tAttrs) {

      var td = "", th = "";

      angular.forEach(tElm.find('column'), function(column){
        th = th + "<th>" + column.title + "</th>";
        td = td + "<td>" + column.innerHTML + "</td>";
      });

      var template = '<table>' + 
                      '<thead>' + th + '</thead>' +
                      '<tbody>' +
                        '<tr ng-repeat="item in items">'+ td +'</tr>' +
                      '</tbody>' +
                    '</table>';
      return template;
    }
  };
});

您还可以使用更多指令构建它:

这是一个演示插件:http://plnkr.co/edit/a3xOSS6Un6XE9b1hQhvw?p=preview

一个用于保存已转换列副本的指令(必须先运行):

app.directive('grid', function() {
  return {
    priority: 1200,
    restrict: 'E',
    compile: function(tElm, tAttrs) {
      tAttrs.columns = tElm.find('column');
      tElm.empty();
    },
    controller: function($attrs) {
      this.columns = $attrs.columns;
    }
  };
});

用于创建隔离范围并用模板替换的其他指令:

app.directive('grid', function() {
  return {
    priority: 1100,
    restrict: 'E',
    scope:{
      items: "="
    },
    templateUrl: 'grid.html'
  };
});

现在我想出了这个模板:

<table>
    <thead title-transclude></thead>
    <tbody>
        <tr ng-repeat="item in items" row-transclude></tr>
    </tbody>
</table>

两个不同的指令来克隆标题和内容。在这些指令中,您可以通过网格控制器引用已转换的列:

app.directive('titleTransclude', function($compile) {
  return {
    require: '^grid',
    link: function(scope, elm, attr, grid) {
      var clones = [];
      angular.forEach(grid.columns, function(col) {
        var th = document.createElement('th');
        th.innerHTML = col.title;
        clones.push(th);
      });
      elm.append(clones);
      $compile(clones)(scope);
    }
  };
});

app.directive('rowTransclude', function($compile) {
  return {
    require: '^grid',
    link: function(scope, elm, attr, grid) {
      var clones = [];
      angular.forEach(grid.columns, function(col) {
        var td = document.createElement('td');
        td.innerHTML = col.innerHTML;
        clones.push(td);
      });
      elm.append(clones);
      $compile(clones)(scope);
    }
  };
});