2014-01-18 40 views
0

我正在嘗試在一個角度指令中動態創建一個表。創建表後,我希望使用我的範圍模型中的未知數據填充表。這個棘手的部分是,我無法創建我的ng-repeat,直到鏈接函數構建了我的表結構。我希望我可以使用transclude功能來完成這個功能,但它不工作,沒有任何事情發生。我在我的表格中看到的所有內容都是{{row.field0}},而不是實際的數據值。如何從指令transclude ng-repeat

PS:下面的代碼示例在打字稿中。

標記

<table table-maker="" column-count="model.getColumnCount()" row-data="model.rowData"> 
</table> 

指令

/// <reference path="../_references.ts" /> 

module Directives { 

    export interface ITableMakerScope extends ng.IScope { 
     columnCount: number; 
     rowData: any[]; 
    } 

    export class TableMakerDirective { 

     public link: Function; 
     public transclude: boolean = true; 
     public scope: any = { 
      columnCount: '=', 
      rowData: '=' 
     } 

     private _scope: ITableMakerScope; 
     private _element: JQuery; 

     constructor() { 
      this.link = this.internalLink.bind(this); 
     } 

     public internalLink(scope: ITableMakerScope, element: JQuery, attrs, ctrl): void { 

      this._scope = scope; 
      this._element = element; 

      var stopWatch = scope.$watch('columnCount', (newValue) => { 
       if (newValue) { 
        this.buildTable(newValue); 
        stopWatch(); 
       } 
      }); 

     } 

     private buildTable(columnCount: number): void { 

      var headerRow = $('<tr>'); 
      var templateRow = $('<tr ng-repeat="row in rowData" ng-transclude="">'); // <-- angular 

      for (var i = 0; i < columnCount; i++) { 

       var th = $('<th>'); 
       th.text('Column {0}'.format((i + 1).padLeft(1))); 
       headerRow.append(th); 

       var td = $('<td>'); 
       td.text('{{row.field{0}}}'.format(i)); // <-- angular 
       templateRow.append(td); 

      } 

      var thead = $('<thead>'); 
      thead.append(headerRow); 
      this._element.append(thead); 

      var tbody = $('<tbody>'); 
      tbody.append(templateRow); 
      this._element.append(tbody); 

     } 

    } 

} 

這是這樣做的正確方法?

謝謝。

+0

你最好預先處理您的數據轉換爲已知對象結構,然後在您的指令中呈現該結構。你能澄清你的意思是不能「創建我的ng-repeat,直到鏈接函數建立了我的表結構之後」? –

+0

@Sly_cardinal謝謝,我如何預處理?你的意思是在編譯功能? – Grant

+0

我的意思是,沒有HTML讓我把我的重複,直到我已經生成它的鏈接功能。 – Grant

回答

1

使用指令中的templatetemplateUrl屬性來保存模板信息。

見預先處理,我會做這樣的事情的數據(根據您的例子)Angular documentation on directives

angular.module('moduleName').directive('tableMaker', function(){ 
    return { 
     replace: true, 
     scope: { 
      columnCount: '=', 
      rowData: '=' 
     }, 
     link: function(scope, element, attr){ 
      var columnCount = null; 
      var rowData = null; 

      // Set up watchers to detect changes to both properties. 
      scope.$watch('columnCount', function(value){ 
       columnCount = value; 
       updateTable() 
      }); 

      scope.$watchCollection('rowData', function(value){ 
       rowData = value; 
       updateTable() 
      }); 


      // This makes sure that we have both the columnCount and data before 
      // generating the table data. 
      function updateTable(){ 
       var tableData = null; 
       if (columnCount && data){ 
        tableData = buildTable(columnCount, data); 
       } 
       scope.tableData = tableData; 
      } 


      // Generate the data that will be used to create the table. 
      // Adjust as needed. 
      function buildTable(columnCount, rowData){ 
       var tableData = { 
        headers: [], 
        rowData: rowData, 
        cellData: [] 
       }; 

       var headers = tableData.headers; 
       var cellData = tableData.cellData; 

       for (var i = 0; i < columnCount; i++){ 
        headers.push('Column {0}'.format((i + 1).padLeft(1))); 
        cellData.push('field'+i); 
       } 

       return tableData; 
      } 
     }, 

     template: 
     '<table>'+ 
      '<thead>'+ 
       '<tr>'+ 
        '<th ng-repeat="header in tableData.headers">{{header}}</th>'+ 
       '</tr>'+ 
      '</thead>'+ 
      '<tbody>'+ 
       '<tr ng-repeat="row in tableData.rowData">'+ 
        '<td ng-repeat="cell in tableData.cellData">{{row[cell]}}</td>'+ 
       '</tr>'+ 
      '</tbody>'+ 
     '</table>' 
    }; 
});