多次出现相同的自定义指令Angular2
Multiple occurrences of the same custom directive Angular2
我目前正在构建一个 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>
以上是我创建的一个可重复使用的指令table。我的一般要求是每页 table。
这是相同的对应组件 -
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) 为其提供数据,这使得代码高度解耦。
这是我陷入困境的地方。如果我想在一个页面上有多个 tables,具有不同的数据和结构,它不能作为每个组件绑定到的服务是 Singleton。
我可以选择不注入服务,并将每个服务作为 setter 提供,但在那种情况下,我需要为每个服务创建子类,目前我不需要这样做。另外,我的代码将变得耦合。
你们认为我可以采取什么方向来解决这个问题?
谢谢,
普拉蒂克
您可以创建指令以在那里提供服务。
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>
我目前正在构建一个 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>
以上是我创建的一个可重复使用的指令table。我的一般要求是每页 table。
这是相同的对应组件 -
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) 为其提供数据,这使得代码高度解耦。
这是我陷入困境的地方。如果我想在一个页面上有多个 tables,具有不同的数据和结构,它不能作为每个组件绑定到的服务是 Singleton。
我可以选择不注入服务,并将每个服务作为 setter 提供,但在那种情况下,我需要为每个服务创建子类,目前我不需要这样做。另外,我的代码将变得耦合。
你们认为我可以采取什么方向来解决这个问题?
谢谢, 普拉蒂克
您可以创建指令以在那里提供服务。
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>