具有自定义html绑定的Angular 2 Datatable可扩展行

时间:2017-02-04 09:09:35

标签: javascript angular typescript angular2-template

我尝试使用数据表,并且能够拥有一个扩展的子行,同时点击+它会消耗行并显示其他数据,其中一些按钮绑定这是ajax版本,然后转移到angular 2:enter image description here

每行包含一行以获取其他操作和信息。

以下是组件:

import {Component, Input, ElementRef, AfterContentInit, OnInit} from '@angular/core';

declare var $: any;

@Component({

  selector: 'sa-datatable',
  template: `
      <table class="dataTable {{tableClass}}" width="{{width}}">
        <ng-content></ng-content>
      </table>
`,
  styles: [
    require('smartadmin-plugins/datatables-bundle/datatables.min.css')
  ]
})
export class DatatableComponent implements OnInit {

  @Input() public options:any;
  @Input() public filter:any;
  @Input() public detailsFormat:any;

  @Input() public paginationLength: boolean;
  @Input() public columnsHide: boolean;
  @Input() public tableClass: string;
  @Input() public width: string = '100%';

  constructor(private el: ElementRef) {
  }

  ngOnInit() {
    Promise.all([
      System.import('script-loader!smartadmin-plugins/datatables-bundle/datatables.min.js'),
    ]).then(()=>{
      this.render()

    })
  }

  render() {
    let element = $(this.el.nativeElement.children[0]);
    let options = this.options || {}


    let toolbar = '';
    if (options.buttons)
      toolbar += 'B';
    if (this.paginationLength)
      toolbar += 'l';
    if (this.columnsHide)
      toolbar += 'C';

    if (typeof options.ajax === 'string') {
      let url = options.ajax;
      options.ajax = {
        url: url,
        // complete: function (xhr) {
        //
        // }
      }
    }

    options = $.extend(options, {

      "dom": "<'dt-toolbar'<'col-xs-12 col-sm-6'f><'col-sm-6 col-xs-12 hidden-xs text-right'" + toolbar + ">r>" +
      "t" +
      "<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
      oLanguage: {
        "sSearch": "<span class='input-group-addon'><i class='glyphicon glyphicon-search'></i></span> ",
        "sLengthMenu": "_MENU_"
      },
      "autoWidth": false,
      retrieve: true,
      responsive: true,
      initComplete: (settings, json)=> {
        element.parent().find('.input-sm', ).removeClass("input-sm").addClass('input-md');
      }
    });

    const _dataTable = element.DataTable(options);

    if (this.filter) {
      // Apply the filter
      element.on('keyup change', 'thead th input[type=text]', function () {
        _dataTable
          .column($(this).parent().index() + ':visible')
          .search(this.value)
          .draw();

      });
    }


    if (!toolbar) {
      element.parent().find(".dt-toolbar").append('<div class="text-right"><img src="assets/img/logo.png" alt="SmartAdmin" style="width: 111px; margin-top: 3px; margin-right: 10px;"></div>');
    }

    if(this.detailsFormat){
      let format = this.detailsFormat
      element.on('click', 'td.details-control', function () {
        var tr = $(this).closest('tr');
        var row = _dataTable.row( tr );
        if ( row.child.isShown() ) {
          row.child.hide();
          tr.removeClass('shown');
        }
        else {
          row.child( format(row.data()) ).show();
          tr.addClass('shown');
        }
      })
    }

  }

}

以下是我如何使用模板html中的另一个组件:

<div  class="well">

    <h1>Store Items</h1>
    <sa-datatable [options]="options"
                  [detailsFormat]="detailsFormat"
                  tableClass="display projects-table table table-striped table-bordered table-hover"
                  width="100%">
        <thead>
        <tr>
            <th data-hide="phone"></th>
            <th data-hide="phone">Item</th>
            <th data-class="expand"><i
                    class="fa fa-fw fa-user text-muted hidden-md hidden-sm hidden-xs"></i>
                UUID
            </th>
            <th data-hide="phone"><i
                    class="fa fa-fw fa-phone text-muted hidden-md hidden-sm hidden-xs"></i>
                Item ID
            </th>
            <th>Profit</th>
            <th data-hide="phone,tablet"><i
                    class="fa fa-fw fa-map-marker txt-color-blue hidden-md hidden-sm hidden-xs"></i>
                FTP Status
            </th>            
        </tr>
        </thead>

    </sa-datatable>


</div>

这是我的组件:

import {Component, OnInit, ChangeDetectionStrategy, ElementRef} from '@angular/core';
import {FadeInTop} from "../../../shared/animations/fade-in-top.decorator";
declare var $: any;
@FadeInTop()
@Component({
    selector: 'store-items',
    templateUrl: './store-items-datatable.html',
    styleUrls: ['./store-items-datatable.css'],
    changeDetection:ChangeDetectionStrategy.OnPush
})
export class StoreItemsDatatable {


    constructor() {

    }

    public options = {       
        "ajax": 'assets/roi/items.json',
        "iDisplayLength": 15,
        "columns": [
            {
                "class": 'details-control',
                orderable: false,
                data: null,
                defaultContent: ''
            },
            //each line is a column
            {data: "title"},
            {data: "uuid"}, 
            {data: "status"},            
        ],
        "order": [[1, 'asc']]
    }

    public detailsFormat(d) {

        return `<table cellpadding="5" cellspacing="0" border="0" class="table table-hover table-condensed">
                    <tr>
                        <td style="width:100px">Actions:</td>
                        <td><a href='${d.generalInfo.link}' target="_blank">Go To Item</a>

                            <td>`+this.getActions(d)+`</td>
                    </tr>                    
                </table>`
    }    

    getActions(data) {
        return `

            <div class="col-xs-12 col-sm-12 col-md-2 col-lg-2">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">Upload Item to FTP</h4>
                    </div>
                    <div class="modal-body">
                        <a class="btn btn-default btn-xs" id="uploadItemToFTP" rel="tooltip" data-placement="top" data-original-title="Upload Item to FTP" (click)='someMethod()'>Upload</a>
                    </div>
                </div>
            </div>`;
    }
}

detailsFormat已使用[detailsFormat]="detailsFormat"

在html模板中传递

问题是,当按下→detailsFormat的方法返回额外的html内容但是按钮的绑定不起作用时,有没有办法在点击+按钮后再次渲染页面上传按钮会起作用吗?

请求的最终结果是(click)='someMethod()'将起作用

1 个答案:

答案 0 :(得分:0)

我们有完全相同的问题。 你有没有找到解决方案?

我终于通过做一个技巧来解决它,因为detailsFormat只有html的引用,我创建一个标签并在标签内插入组件,并返回要附加到datatable的div。 这很简单但不容易。效果很好!!

在dataTable.component中的

,有一个Input()detailComponent,你从你的html页面发送为[detailComponent] =“details”

然后在调用detailsFormat的地方执行:

 row.child(detailComponent.location.nativeElement).show();

现在,在下面有detailFormats的文件中:

public detailFormats () {

    var componentFactory = this.resolver.resolveComponentFactory(ProjectDetailsComponent);
    var newNode = document.createElement('div');
    newNode.id = 'detailHolder';
    var ref = componentFactory.create(this.injector, [], newNode);
    this.app.attachView(ref.hostView);
    return ref;

}

“YourComponent”是您在用户点击+按钮时要显示的html的组件。

如果要将数据传递给组件,请在行前的DataTable.component中添加:

(detailComponent.instance).model = row.data();

类似的方法: https://angular.io/guide/dynamic-component-loader