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

Javascript 具有自定义html绑定的Angular 2 Datatable可扩展行,javascript,angular,typescript,angular2-template,Javascript,Angular,Typescript,Angular2 Template,我正在尝试使用数据表,并能够在单击+的同时拥有一个扩展的子行,它将扩展该行,并通过一些按钮显示附加数据。这是ajax版本,然后移动到angular 2: 每一行都有一个子行用于其他操作和信息 以下是组件: import {Component, Input, ElementRef, AfterContentInit, OnInit} from '@angular/core'; declare var $: any; @Component({ selector: 'sa-datatable

我正在尝试使用数据表,并能够在单击+的同时拥有一个扩展的子行,它将扩展该行,并通过一些按钮显示附加数据。这是ajax版本,然后移动到angular 2:

每一行都有一个子行用于其他操作和信息

以下是组件:

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

  }

}
import{Component,Input,ElementRef,AfterContentInit,OnInit}来自'@angular/core';
声明var$:任何;
@组成部分({
选择器:“sa数据表”,
模板:`
`,
风格:[
require('smartadmin-plugins/datatables bundle/datatables.min.css')
]
})
导出类DatatableComponent实现OnInit{
@Input()公共选项:任意;
@Input()公共过滤器:任意;
@Input()公共详细信息格式:任意;
@Input()公共分页长度:布尔值;
@Input()public columnsHide:boolean;
@Input()公共表类:string;
@Input()公共宽度:字符串='100%';
构造函数(专用el:ElementRef){
}
恩戈尼尼特(){
我保证([
System.import('script-loader!smartadmin plugins/datatables bundle/datatables.min.js'),
]).然后(()=>{
this.render()
})
}
render(){
let element=$(this.el.nativeElement.children[0]);
设options=this.options | |{}
让工具栏=“”;
如果(选项.按钮)
工具栏+=‘B’;
如果(此分页长度)
工具栏+='l';
如果(本栏第二栏)
工具栏+='C';
if(typeof options.ajax=='string'){
让url=options.ajax;
options.ajax={
url:url,
//完成:函数(xhr){
//
// }
}
}
选项=$.extend(选项{
“dom”:”+
“t”+
"",
语言:{
“搜索”:“搜索”,
“长菜单”:“\u菜单”
},
“自动宽度”:false,
检索:对,
回答:是的,
initComplete:(设置,json)=>{
element.parent().find('.input-sm',).removeClass(“input-sm”).addClass('input-md');
}
});
const _dataTable=element.dataTable(选项);
if(this.filter){
//应用过滤器
元素上('keyup change','thead th input[type=text]',函数(){
_数据表
.column($(this).parent().index()+':visible')
.search(此.value)
.draw();
});
}
如果(!工具栏){
element.parent().find(“.dt工具栏”).append(“”);
}
如果(此.details格式){
让format=this.detailsFormat
元素('click','td.details control',函数(){
var tr=$(this.nexist('tr');
var行=_dataTable.row(tr);
if(row.child.isShown()){
row.child.hide();
tr.removeClass(“显示”);
}
否则{
row.child(格式(row.data()).show();
tr.addClass(“显示”);
}
})
}
}
}
下面是我如何从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>

储存物品
项目
UUID
项目ID
利润
FTP状态
以下是我的组件:

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>`;
    }
}
从'@angular/core'导入{Component,OnInit,changedtectionstrategy,ElementRef};
从“../../shared/animations/fade-in-top.decorator”导入{FadeInTop}”;
声明var$:任何;
@法代恩托普()
@组成部分({
选择器:“存储项目”,
templateUrl:“./storeitems datatable.html”,
样式URL:['./存储项datatable.css'],
changeDetection:ChangeDetectionStrategy.OnPush
})
导出类StoreItemsDataable{
构造函数(){
}
公共选项={
“ajax”:“assets/roi/items.json”,
“iDisplayLength”:15,
“栏目”:[
{
“类”:“详细信息控制”,
可订购:错误,
数据:空,
默认内容:“”
},
//每行是一列
{数据:“标题”},
{数据:“uuid”},
{数据:“状态”},
],
“订单”:[[1,‘asc']]
}
公开资料格式(d){
返回`
行动:
`+这个.getActions(d)+`
`
}    
getActions(数据){
返回`
将项目上载到FTP
上传
`;
}
}
使用
[detailsFormat]=“detailsFormat”

问题是,当按下+时,detailsFormat方法返回额外的html内容,但按钮的绑定不起作用,是否有办法在单击+按钮后再次呈现页面,从而使与上载按钮的绑定起作用


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

我们有完全相同的问题。 你有没有找到解决办法

我最终通过一个技巧解决了这个问题,因为detailsFormat只引用html,所以我创建了一个标记并将组件插入标记中,然后返回要附加到datatable的div。 这很简单,但并不容易。很好

在dataTable.component中,有一个Input()detailComponent,您将从html页面将其作为[detailComponent]=“details”发送

然后在调用Details Format do的位置:

 row.child(detailComponent.location.nativeElement).show();
现在,在具有详细信息格式的文件中,请执行以下操作:

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的组件,当用户单击+按钮时,您希望显示该html

如果要将数据传递给组件,请在行lin之前的DataTable.component中
(detailComponent.instance).model = row.data();