添加按钮到表格图表(AngularJS / Google Charts)

时间:2015-03-31 13:54:41

标签: angularjs google-visualization

我正在尝试在Table Charts应用中使用AngularJS 1.2.10组件。

我编写了一个包装器指令,它将表格图表放入AngularJS上下文中。

    angular.module('my.charts.table', [])
        .directive('myTableChart', [function() {
            return {
                restrict : 'E',
                scope : {
                    columns : '=',
                    rows : '='
                },
                templateUrl : 'my.charts.table/myTableChart.tmpl.html',
                link : function(scope, element) {
                    var data = new google.visualization.DataTable();

                    // add columns

                    var table = new google.visualization.Table(element[0].childNodes[0]);

                    table.draw(data, { allowHtml : true }); 
                } 
           };
       }
  ]);

对于给定的列和行,数据表将被初始化并绘制。

我想要做的是添加一个列,其中包含一个带有AngularJS指令的按钮。

<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="testLog()">Test</button>

您可以假设 testLog()方法是在当前范围内定义的。

表格图表组件允许直接插入HTML作为单元格值。但是,这不在AngularJS生命周期之内,因此,只需插入上述HTML代码段就无法工作。

现在,我尝试手动编译和链接按钮。

var btn = $compile('<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="testLog()">Test</button>')(scope);

我可以手动附加按钮。

element.append(btn);

但是,表格图表需要HTML,而不是DOM元素。 如果我传递 btn [0] .outerHTML ,则ngClick指令不会触发。

有没有办法解决这个问题?

以下是完整的代码段:

&#13;
&#13;
google.load('visualization', '1', {
  packages: ['corechart', 'table']
});

google.setOnLoadCallback(function() {
  angular.bootstrap(document, ['my.app']);
});

angular.module('my.app', [])
  .directive('myTableChart', function() {
    return {
      restrict: 'E',
      scope: {
        columns: '=',
        rows: '='
      },
      template: '<div></div>',
      link: function(scope, element) {
        var data = new google.visualization.DataTable();

        for (var i = 0; i < scope.columns.length; i++) {
          data.addColumn(scope.columns[i].type, scope.columns[i].name);
        }

        data.addRows(scope.rows);

        var table = new google.visualization.Table(element[0].childNodes[0]);
        table.draw(data, {
          width: '100%',
          allowHtml: true
        });
      }
    };
  })
  .directive('myTestTable', ['$compile',
    function($compile) {
      return {
        restrict: 'E',
        scope: {},
        template: '<my-table-chart ng-if="curRows != null" columns="curCols" rows="curRows"></my-table-chart>',
        link: function(scope, element) {
          scope.curCols = [{
            type: 'string',
            name: 'Test'
          }, {
            type: 'string',
            name: ''
          }];

          scope.curRows = [];

          scope.testLog = function() {
            alert('Works too');
          };

          var btn = $compile('<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="testLog()">Test</button>')(scope);

          var btnHtml = btn[0].outerHTML;

          element.append(btn);

          scope.curRows.push(['test entry', btnHtml]);
        }
      };
    }
  ]);
&#13;
<my-test-table></my-test-table>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>

<script src="https://www.google.com/jsapi"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

迟到总比没有好,以下解决方案允许通过testLog指令触发ng-click事件:

  • 由于Google Chart google.visualization.Table不支持 添加DOM元素,将编译从myTestTable移到 myTableChart
  • testLog指令范围访问myTableChart函数,将声明更改为ng-click="$parent.testLog()"
  • 渲染图表后执行编译:

    google.visualization.events.addListener(table, 'ready', function() {
        var table_div = table.getContainer();
        $compile(table_div)(scope); 
    });  
    

示例

google.load('visualization', '1', {
  packages: ['corechart', 'table']
});

google.setOnLoadCallback(function() {
  angular.bootstrap(document, ['my.app']);
});

angular.module('my.app', [])
  .directive('myTableChart', function($compile) {
    return {
      restrict: 'E',
      scope: {
        columns: '=',
        rows: '='
      },
      template: '<div></div>',
      link: function(scope, element) {
        var data = new google.visualization.DataTable();

        for (var i = 0; i < scope.columns.length; i++) {
          data.addColumn(scope.columns[i].type, scope.columns[i].name);
        }

        data.addRows(scope.rows);

        var table = new google.visualization.Table(element[0].childNodes[0]);
        google.visualization.events.addListener(table, 'ready', function() {
            var table_div = table.getContainer();
            $compile(table_div)(scope); 
        });  

        table.draw(data, {
          width: '100%',
          allowHtml: true
        });
      }
    };
  })
  .directive('myTestTable', ['$compile',
    function($compile) {
      return {
        restrict: 'E',
        scope: {},
        template: '<my-table-chart ng-if="curRows != null" columns="curCols" rows="curRows"></my-table-chart>',
        link: function(scope, element) {
          scope.curCols = [{
            type: 'string',
            name: 'Test'
          }, {
            type: 'string',
            name: ''
          }];

          scope.curRows = [];

          scope.testLog = function() {
            alert('Works too');
          };

          var btnHtml = '<button class="btn btn-primary" onclick="alert(\'Works\')" ng-click="$parent.testLog()">Test</button>';
          scope.curRows.push(['test entry', btnHtml]);
        }
      };
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="https://www.google.com/jsapi"></script>

<my-test-table></my-test-table>