AngularJS和Datatable - 在重新渲染单元格值时编译html

时间:2022-08-01 20:11:51

I am using angularjs and datatable to build a grid. I have a following javascript code,

我正在使用angularjs和datatable来构建网格。我有以下javascript代码,

DEMO: http://plnkr.co/edit/qJ7vr1Bec5OdRrxpHw2Q?p=preview

datatable_config = {
     "bJQueryUI": true,
     "bProcessing": true,
     "bDeferRender": true,
     "sDom": "Rlfrtip",
     "aaData": [null]
};

angular.forEach(columns, function(column, key){
    datatable_config.aoColumns.push({
        "sTitle": column.displayName, 
        "mData": function(source, type, value){
            var cell_value = (source[column.field]) ? source[column.field] : '', rendered_cell;
            if(column.field == 'something'){
                rendered_cell = $compile('<span>{{$root.value}}</span>')($scope);
                 /* For this column, I am not getting the span element with the evaluated rootscope instead, it says [object object] */
            } else {
                rendered_cell = cell_value;
            }
            return rendered_cell;
        }
    });
});

When I compile the HTML, it displays [object object]. I am getting the problem, we need to compile it after the bind, like this element.html(value); $compile(element.contents())(scope);. But it is not possible in the above code. Any solution or idea?

当我编译HTML时,它显示[对象对象]。我遇到问题,我们需要在绑定后编译它,就像这个element.html(value); $编译(element.contents())(范围);.但是在上面的代码中是不可能的。任何解决方案或想法?

Thanks in advace.

谢谢你的推荐。

3 个解决方案

#1


1  

Had Similar Issue trying to compile "to be rendered DOM". After hours finally made it work, though my requirements were lot different. I needed to bind directives also, for which you need to use $compile().

有类似问题试图编译“渲染DOM”。经过几个小时的努力终于成功了,尽管我的要求很不一样。我还需要绑定指令,你需要使用$ compile()。

For your use case, Use $parse

对于您的用例,请使用$ parse

// parse the "value" attribute value into a function
var parseFn = $parse(value);
// "parseFn" is a function that can be invoked to get the expression's value 
// providing a scope
var currVal = parseFn($root);

// return updated markup
return '<span>'+ currVal +'</span>';

#2


1  

I think it is a little bit late but I have a simpler solution to this issues but I still recommend you to use angular-datatable directive.

我认为这有点晚了但我对这个问题有一个更简单的解决方案,但我仍然建议你使用angular-datatable指令。

data_table.directive('dataTable', ['$log', '$timeout', '$compile', function($log, $timeout, $compile){
return {
    restrict: 'C',
    controller : ['$rootScope', '$scope', '$element', function ($rootScope, $scope, $element){
        var grid_table, 
        datatable_config = {
            "bJQueryUI": true,
            "bProcessing": true,
            "bDeferRender": true,
            "sDom": "Rlfrtip",
            "aaData": [
              {'name': 'Aravind'}
            ]
        };

        datatable_config.aoColumns = [];

        datatable_config.aoColumns.push({
            "sTitle": 'Name', 
            "mData": function(source, type, value){
                //No need to compile the value
                var direct = '<span>' + source.name +'</span>';
                return  direct;
            }
        });

        grid_table = $element.dataTable(datatable_config);
    }]
}

}]);

Thanks, I hope this could help someone else.

谢谢,我希望这可以帮助别人。

#3


0  

Try this

$scope.tableData = []; // just initialize an array to store data coming from server

      // watch each change in the server-side data to reload grid table
      $scope.$watch("tableData", function (data) {
        $scope.tableParams.reload();
      });

      // Set ng-table parameters with pagination
        $scope.tableParams = new ngTableParams({
          page: 1,      // show first page
        count: 10     // count per page
      }, {
        total: $scope.tableData.length, // length of data
        $scope: {},
        getData: function($defer, params) {
          var filteredData = $scope.tableData;
          // use build-in angular filter
          var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : filteredData;
          orderedData = params.filter() ? $filter('filter')(orderedData, params.filter()) : orderedData;
          params.total(orderedData.length); // set total for recalc pagination
          $defer.resolve($scope.results = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
        }
      });

Table should be like this

表应该是这样的

<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered datatables"  ng-table="tableParams"  show-filter="true">
   <tbody>
      <tr ng-repeat="tableData in $data">
         <!-- Checkbox -->
         <td data-title="''"  class="center" header="'ng-table/headers/checkbox.html'" width="4">
            <input type="checkbox" ng-model="checkboxes.items[tableData.id]" />
         </td>
         <!-- name-->
         <td data-title="some title" sortable="'name'" filter="{ 'name': 'text' }">
            <span ng-if="!tableData.$edit">{{tableData.name}}</span> <!--here name should be as same field as in data base-->
         </td>
   </tbody>
</table>

#1


1  

Had Similar Issue trying to compile "to be rendered DOM". After hours finally made it work, though my requirements were lot different. I needed to bind directives also, for which you need to use $compile().

有类似问题试图编译“渲染DOM”。经过几个小时的努力终于成功了,尽管我的要求很不一样。我还需要绑定指令,你需要使用$ compile()。

For your use case, Use $parse

对于您的用例,请使用$ parse

// parse the "value" attribute value into a function
var parseFn = $parse(value);
// "parseFn" is a function that can be invoked to get the expression's value 
// providing a scope
var currVal = parseFn($root);

// return updated markup
return '<span>'+ currVal +'</span>';

#2


1  

I think it is a little bit late but I have a simpler solution to this issues but I still recommend you to use angular-datatable directive.

我认为这有点晚了但我对这个问题有一个更简单的解决方案,但我仍然建议你使用angular-datatable指令。

data_table.directive('dataTable', ['$log', '$timeout', '$compile', function($log, $timeout, $compile){
return {
    restrict: 'C',
    controller : ['$rootScope', '$scope', '$element', function ($rootScope, $scope, $element){
        var grid_table, 
        datatable_config = {
            "bJQueryUI": true,
            "bProcessing": true,
            "bDeferRender": true,
            "sDom": "Rlfrtip",
            "aaData": [
              {'name': 'Aravind'}
            ]
        };

        datatable_config.aoColumns = [];

        datatable_config.aoColumns.push({
            "sTitle": 'Name', 
            "mData": function(source, type, value){
                //No need to compile the value
                var direct = '<span>' + source.name +'</span>';
                return  direct;
            }
        });

        grid_table = $element.dataTable(datatable_config);
    }]
}

}]);

Thanks, I hope this could help someone else.

谢谢,我希望这可以帮助别人。

#3


0  

Try this

$scope.tableData = []; // just initialize an array to store data coming from server

      // watch each change in the server-side data to reload grid table
      $scope.$watch("tableData", function (data) {
        $scope.tableParams.reload();
      });

      // Set ng-table parameters with pagination
        $scope.tableParams = new ngTableParams({
          page: 1,      // show first page
        count: 10     // count per page
      }, {
        total: $scope.tableData.length, // length of data
        $scope: {},
        getData: function($defer, params) {
          var filteredData = $scope.tableData;
          // use build-in angular filter
          var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : filteredData;
          orderedData = params.filter() ? $filter('filter')(orderedData, params.filter()) : orderedData;
          params.total(orderedData.length); // set total for recalc pagination
          $defer.resolve($scope.results = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
        }
      });

Table should be like this

表应该是这样的

<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered datatables"  ng-table="tableParams"  show-filter="true">
   <tbody>
      <tr ng-repeat="tableData in $data">
         <!-- Checkbox -->
         <td data-title="''"  class="center" header="'ng-table/headers/checkbox.html'" width="4">
            <input type="checkbox" ng-model="checkboxes.items[tableData.id]" />
         </td>
         <!-- name-->
         <td data-title="some title" sortable="'name'" filter="{ 'name': 'text' }">
            <span ng-if="!tableData.$edit">{{tableData.name}}</span> <!--here name should be as same field as in data base-->
         </td>
   </tbody>
</table>