如何从指令中转换ng-repeat

时间:2014-01-18 00:22:01

标签: angularjs angularjs-directive typescript

我试图在angular指令中动态创建一个表。在创建表之后,我希望使用范围模型中的未知数据填充表。其中最棘手的部分是,在链接函数构建了我的表结构之前,我无法创建ng-repeat。我希望我可以使用transclude函数来实现这一点,但它不起作用,没有任何事情发生。我在表格中看到的只是{{row.field0}}而不是实际的数据值。

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);

        }

    }

}

这是正确的方法吗?

感谢。

1 个答案:

答案 0 :(得分: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>'
    };
});