【问题标题】:Angular 2 Datatable expandable row with custom html binding带有自定义html绑定的Angular 2 Datatable可扩展行
【发布时间】:2017-02-04 09:09:34
【问题描述】:

我正在尝试使用数据表,并且能够在单击 + 时拥有扩展的子行,它将扩展该行并显示带有一些绑定按钮的附加数据这是移动到 angular 2 之前的 ajax 版本:

每一行都是一个子行,用于附加操作和信息。

这是组件:

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()' 可以工作

【问题讨论】:

    标签: javascript angular typescript angular2-template


    【解决方案1】:

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

    我终于通过一个技巧解决了它,因为detailsFormat只有对html的引用,所以我创建一个标签并将组件插入标签内,并返回要附加到数据表的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

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 2015-04-05
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 2015-10-23
      • 2016-03-28
      相关资源
      最近更新 更多