多次出现相同的自定义指令Angular2

时间:2017-08-18 14:56:04

标签: javascript angular angular2-services angular2-directives

我目前正在构建一个Angular应用程序,我试图在指令(作为组件)的帮助下使代码具有高度可重用性。

<div class="container container-fluid" >
  <div class="row">
    <table class="table table-responsive table-hover">
      <thead class="thead-inverse">
      <tr>
        <th *ngFor="let column of columns">{{column.header}}</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let row of rows;trackBy: trackByID;">
        <td *ngFor="let column of columns">{{row[column.field]}}
        </td>
      </tr>
      </tbody>
    </table>
  </div>
  <xfd-progressbar></xfd-progressbar>
  <div class="row col-lg-offset-5">
    <ngbd-pagination-basic></ngbd-pagination-basic>
  </div>
</div>

以上是我创建的具有可重用表的指令。我的一般要求是我每页都有一个表格。

这里是相应的组件 -

import {Column} from "../models/Column";
import {Component, OnInit} from "@angular/core";
import {PaginationService} from "../services/PaginationService";
import {GridLoadUtil} from "../util/GridLoadUtil";
import {ProgressBarService} from "../services/ProgressBarService";

/**
 * Created by ppandey on 6/12/2017.
 */

@Component({
    selector: 'xfd-table',
    templateUrl: './table.component.html',
    styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit{
  columns: Column[]= [];
  rows: any[] = [];

  constructor(private paginService: PaginationService,
            private tableLoader: GridLoadUtil,
            private progressBarService: ProgressBarService) {
    this.paginService.itemsToDisplayChange.subscribe((value) => {
      this.rows = value
    });

    this.tableLoader.columnsChange.subscribe((values) => {
      this.columns = values;
    });
  }

  ngOnInit() {
    this.tableLoader.beforeDataLoaded();
    this.progressBarService.startProgress();
  }
}

如您所见,我的组件使用Services(GridLoadUtil)为其提供数据,这使代码高度分离。

这是我进入泡菜的地方。如果我想在一个页面上拥有多个表,具有不同的数据和结构,那么每个组件所依赖的服务就是Singleton。

我可以选择不注入服务,并将每个服务作为setter提供,但在这种情况下,我需要为每个服务创建子类,这是我目前不需要的。此外,我的代码将耦合。

你认为我可以采取任何方向来解决这个问题吗?

谢谢, PRATIK

1 个答案:

答案 0 :(得分:1)

您可以创建指令以在那里提供服务。 Angulars DI会在寻找TableLoader服务时找到该提供商,因为它最接近该组件(如果该组件本身没有提供):

@Directive({
  selector: [tableLoader1],
  providers: [{provide: GridLoadUtil, useClass: GridLoadUtil1}],
})
class TableLoader1Directive {}

@Directive({
  selector: [tableLoader2],
  providers: [{provide: GridLoadUtil, useClass: GridLoadUtil2}],
})
class TableLoader2Directive {}

然后你可以像

一样使用它
<xfg-table tableLoader1></xfg-table>
<xfg-table tableLoader2></xfg-table>