转换包含ng-binds的HTML

时间:2014-12-19 21:37:17

标签: javascript html angularjs ngtable angular-directive

我正在使用angular指令来包含ng-table一些过滤/导出功能。它的目的是可以重用多个表,因此<td>元素必须是动态的。我试图通过使用ng-transclude

来处理这个问题

问题是我的<td>元素需要一些指令,例如ng-binddata-titlesortable。当它们试图被指令转换时,它们已被渲染为空值。我需要一种方法来防止<td>行被渲染,直到它们被插入到指令

这是我的观点标记:

<div>
   <my-data-table search-filter="ss" table-values="mvData">
     <td data-title="'UUID' | translate" sortable="'id'" ng-bind="row.uuid | shortUuid"></td>
     <td data-title="'DEVICE.UNAME' | translate" sortable="'uname'" ng-bind="row.uname"></td>
     <td data-title="'DEVICE.LOGIN' | translate" sortable="'last_login'">{{{true: (row.last_login | selectedTimezone | moment:'MMM D, YYYY h:mma'), false: 'N/A'}[!!row.last_login]}}</td>
   </my-data-table>
</div>

指令模板:

<div class="row">
  <div class="col-sm-12">
    <table ng-table="mvData.tableParams" class="table table-striped table-hover table-bordered" template-pagination="src/tables/responsive-pager.html">
      <tr ng-repeat="row in $data">
        <div ng-transclude></div>
      </tr>
    </table>
  </div>
</div>

指令声明:

angular.module('myApp')
.directive('myDataTable',function() {

    return {
        restrict:'E'
      , templateUrl:'src/tables/myDataTable.tpl.html'
      , transclude:true
      , scope: {
            searchFilter:'='
          , tableValues:'='
        }
      , link:function(scope,el,attr,ctrls) {
          console.log('hello world');
        }
      }
});

1 个答案:

答案 0 :(得分:1)

部分问题在于,当您将表和列拆分为指令和转换内容时,Angular会因为对无效HTML尝试DOM操作而感到困惑(<td>元素不能存在于一个<table><tr>个元素。)

要解决这个问题,您需要做几件事:

  1. 而不是<td>在被抄送的内容中,您需要更改 这些到<div>(这些将在以后替换为<td>

  2. 您的模板声明将更加复杂,因此您可以将模板完全构造为字符串。在这里,您可以使用逻辑来创建所需的HTML。将此字符串模板传递给Angular后,所有其余的机器都应该可以工作。基本上,您可以手动转录内容。

  3. 这是一个包含ng-table声明的示例,但为简单起见,并未包含ng-table指令:

    <html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
    </head>
    <body ng-app="myApp">
    <div ng-controller="MainCtrl">
       <my-data-table search-filter="ss" table-values="mvData">
         <div data-title="'UUID' | translate" sortable="'id'" ng-bind="row.uuid"></div>
         <div data-title="'DEVICE.UNAME' | translate" sortable="'uname'" ng-bind="row.uname"></div>
         <div data-title="'DEVICE.LOGIN' | translate" sortable="'last_login'"></div>
       </my-data-table>
    </div>
    </body>
    <script>
        var app = angular.module('myApp',[]);
    
        app.controller("MainCtrl", function($scope){
            $scope.mvData= {
                $data : [
                    {uuid : 'abc', uname : 'test'},
                    {uuid : 'abc1', uname : 'test1'},
                    {uuid : 'abc2', uname : 'test2'},
                    {uuid : 'abc3', uname : 'test3'}
                ]
            };
        })
    
        app.directive('myDataTable',function() {
            return {
                restrict:'E',
                template : function(elem, attr){
                    var startStr = 
                        '<div class="row">' + 
                            '<div class="col-sm-12">' + 
                                '<table ng-table="mvData.tableParams" class="table table-striped table-hover table-bordered" template-pagination="src/tables/responsive-pager.html">' + 
                                    '<tbody><tr ng-repeat="row in tableValues.$data">';
                    var endStr =    '</tr></tbody>' +
                                '</table>' + 
                            '</div>' + 
                        '</div>';
    
                    var template = startStr;
                    var colStr;
                    angular.forEach(elem.find("div"), function(item){
                        colStr = item.outerHTML.replace('<div ','<td ').replace('</div>','</td>');
                        template = template + colStr;
                    });
    
                    template = template + endStr;
                    return template;
                },
                scope: {
                    searchFilter:'='
                  , tableValues:'='
                }, 
              }
        });
    
    
    
    </script>
    
    </html>