如何使用可观察对象作为数据源时使角度数据表更新行,结果数和分页

时间:2019-06-07 15:11:36

标签: angular typescript angular-datatables

我试图在我的angular 7应用程序中使用angular-datatables作为显示搜索结果的组件。

request-creation-component创建一个搜索表单,然后单击“提交”按钮,然后使用request-service将http Post请求发送到后端,然后request-creation-component更新request-service中的observable请求结果组件已订阅。

我的问题是,用于显示结果的数据表在获得新结果时不会更新行,结果数和分页按钮。

行,结果数和分页按钮与第一次显示数据表相同。

请求结果组件代码

requestResponse;
resultsAreFound = true;
constructor(private requestService: RequestService) { }
public dataTable: DataTable;

ngOnInit() {
        this.dataTable =  {headerRow : null, footerRow: null, dataRows: null };

        this.requestService.currentSearchResult.subscribe(result => {
            this.requestResponse = result;
            if (result.length > 0) {
            this.resultsAreFound = true;
             // If it gets results, the datatable is assigned the new data. 
                this.dataTable.headerRow = Object.keys(this.requestResponse[0]);
                this.dataTable.footerRow = Object.keys(this.requestResponse[0]);
                this.dataTable.dataRows = this.requestResponse.map(function(i: { [s: string]: {}; } | ArrayLike<{}>) {
                        return Object.values(i);
                    });
            } else {
                // If it gets empty result, the datatable will be hidden and "0 results" message appears.
                this.resultsAreFound = false;
            }
         });
        }

ngAfterViewInit() {
        $('#datatable').DataTable({
            'pagingType': 'full_numbers',
            'lengthMenu': [
                [10, 25, 50, -1],
                [10, 25, 50, 'All']
            ],
            responsive: true,
            language: {
                search: '_INPUT_',
                searchPlaceholder: 'Search records',
            }
        });

请求结果组件模板

<div class="main-content" style="margin-top: 50px;">
        <div class="row">
            <div class="col-md-12">
                <div class="card">
                  <div [hidden]="resultsAreFound" class="card-header">
                    <h4 class="card-title">0 Resultats trouvées.</h4>
                  </div>
                    <div [hidden]="!resultsAreFound" class="card-body">
                        <div class="toolbar">
                        </div>
                          <table id="datatable" class="table table-striped table-bordered" cellspacing="0" width="100%">
                                <thead>
                                    <tr>
                                      <th>{{ dataTable.headerRow[0] }}</th>
                                      <th>{{ dataTable.headerRow[1] }}</th>
                                      <th>{{ dataTable.headerRow[2] }}</th>
                                      <th>{{ dataTable.headerRow[3] }}</th>
                                      <th>{{ dataTable.headerRow[4] }}</th>
                                      <th class="disabled-sorting text-right">{{ dataTable.headerRow[5] }}</th>
                                    </tr>
                                </thead>
                                <tfoot>
                                    <tr>
                                      <th>{{ dataTable.footerRow[0] }}</th>
                                      <th>{{ dataTable.footerRow[1] }}</th>
                                      <th>{{ dataTable.footerRow[2] }}</th>
                                      <th>{{ dataTable.footerRow[3] }}</th>
                                      <th>{{ dataTable.footerRow[4] }}</th>
                                      <th>{{ dataTable.footerRow[5] }}</th>
                                    </tr>
                                </tfoot>
                                <tbody>
                                    <tr *ngFor="let row of dataTable.dataRows">
                                        <td>{{row[0]}}</td>
                                        <td>{{row[1]}}</td>
                                        <td>{{row[2]}}</td>
                                        <td>{{row[3]}}</td>
                                        <td>{{row[4]}}</td>
                                        <td class="text-right">
                                          <a href="#" class="btn btn-danger btn-link btn-icon btn-sm remove"><i class="fa fa-times"></i></a>
                                        </td>

                                    </tr>
                                </tbody>
                            </table>
                    </div>
                    <!-- end content-->
                </div>
                <!--  end card  -->
            </div>
            <!-- end col-md-12 -->
        </div>
        <!-- end row -->
</div>




1 个答案:

答案 0 :(得分:0)

angular-datatable(datatables.net库的包装器)不支持动态数据源,因此在创建表时不能更改数据。

因此,要解决该问题,每次数据更改时我都必须重新创建表。

这是代码,request-results.component.ts文件:

import { Component, OnInit, OnDestroy, AfterViewInit, ViewChild } from '@angular/core';
import { RequestService } from '../services/request.service';
import { Subject } from 'rxjs/internal/Subject';
import { DataTableDirective } from 'angular-datatables';

declare var $: any;

declare interface DataTable {
    headerRow: string[];
    dataRows: string[][];
}

@Component({
    selector: 'app-request-results',
    templateUrl: './request-results.component.html'
})

export class RequestResultsComponent implements OnDestroy, AfterViewInit, OnInit {

@ViewChild(DataTableDirective)
dtElement: DataTableDirective;

public hideTheResults = false;
private notFirstTime = false; // if the data table is going to be used again with new data, it has to be recreated
requestResponse;
resultsAreFound = true;
dtOptions: DataTables.Settings = {
    columnDefs: [ { orderable: false, targets: [4, 5] } ],
    retrieve: true,
    autoWidth: true,
    pagingType: 'full_numbers',
    lengthMenu : [
        [10, 25, 50, -1],
        [10, 25, 50, 'All']
        ],
    responsive: true,
    language: {
    search: '_INPUT_',
    searchPlaceholder: 'Search records',
}};
dtTrigger = new Subject();
public dataTable: DataTable;

constructor(private requestService: RequestService) { }

ngOnInit() {
    this.dataTable =  {headerRow : null, footerRow: null, dataRows: null };
    this.dataTable.headerRow = ['Col1', 'Col2', 'Col3', 'Col4', 'Col5'];
    this.requestService.currentSearchResult.subscribe(result => {
        this.requestResponse = result;
        if (result.length > 0) {
            const table = $('#datatable').DataTable();
            table.destroy();
            this.resultsAreFound = true;
            if (this.notFirstTime) {
                this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
                    dtInstance.destroy();
                });
            }
            this.notFirstTime = true;
            this.dataTable.dataRows = this.requestResponse.map(
                function(i: { [s: string]: {}; } | ArrayLike<{}>) { return Object.values(i);
                });

            this.dtTrigger.next();
        } else {
            this.notFirstTime = true;
            this.resultsAreFound = false;
        }
    });
}

ngOnDestroy(): void {
    this.dtTrigger.unsubscribe();
}

ngAfterViewInit() {
    this.dtTrigger.next();
}

和request-results.component.html文件:

<div class="main-content" style="margin-top: 50px; padding-left: 0px; padding-right: 0px">
<div class="row">
    <div class="col-md-12">
        <div class="card">
            <div [hidden]="resultsAreFound" class="card-header">
            <h4 class="card-title">0 Resultats trouvées.</h4>
            </div>
            <div [hidden]="!resultsAreFound || hideTheResults" class="card-body">
                <h4 class="card-title">Profils trouvées:</h4>
                <div class="toolbar">
                    <!--        Here you can write extra buttons/actions for the toolbar              -->
                </div>
                    <table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table table-striped table-bordered">
                        <thead>
                            <tr>
                                <th>{{ dataTable.headerRow[0] }}<span></span></th>
                                <th>{{ dataTable.headerRow[1] }}<span></span></th>
                                <th>{{ dataTable.headerRow[2] }}<span></span></th>
                                <th>{{ dataTable.headerRow[3] }}<span></span></th>
                                <th>{{ dataTable.headerRow[4] }}<span></span></th>
                                <th><span></span></th>
                            </tr>
                        </thead>
                        <tfoot>
                            <tr>
                                <th>{{ dataTable.footerRow[0] }}</th>
                                <th>{{ dataTable.footerRow[1] }}</th>
                                <th>{{ dataTable.footerRow[2] }}</th>
                                <th>{{ dataTable.footerRow[3] }}</th>
                                <th>{{ dataTable.footerRow[4] }}</th>
                                <th></th>
                            </tr>
                        </tfoot>
                        <tbody>
                            <tr *ngFor="let row of dataTable.dataRows">
                                <td>{{row[0]}}</td>
                                <td>{{row[1]}}</td>
                                <td>{{row[2]}}</td>
                                <td>{{row[3]}}</td>
                                <td>
                                    <a class="btn btn-info btn-link btn-icon btn-sm like"  href="{{row[4]}}" title="LinkedIn"><i class="fa fa-linkedin"></i></a>
                                </td>
                            </tr>
                        </tbody>
                    </table>
            </div>
            <!-- end content-->
        </div>
        <!--  end card  -->
    </div>
    <!-- end col-md-12 -->
</div>
    <!-- end row -->