每个(一组)组件分隔角度服务的实例



TLDR:

如何将 Angular (6( 服务的一个实例用于一组组件(和指令(的(实例(,而将另一个实例用于另一组相同的组件。

或提供更多信息:

我目前正在为基于 Angular 6 的应用程序中的表添加排序功能。因为我使用的是自定义样式(基于物化(,所以大多数库都不适合我。我发现了这个很好的例子,它完全独立于使用的样式。

它创建一个添加到每个<th>标头的SortableColumnComponent和一个添加到<table>元素的SortableTableDirective。它们通过一个SortService进行通信,该基本上只提供一个 RxJS 主题,以便在排序方向/属性更改时通知其他列。

这里的问题是,只要一次只显示一个可排序的表,这就可以很好地工作。但是,添加更多内容后,排序一次只能应用于一个(因为它们都共享相同的服务(。

根据角度文档,当您仅将服务注入应用程序根目录时,服务会自动成为单例(我做到了(。因此,我尝试仅将其注入可排序列:

@Component ({
selector: '[sortable-column]',
templateUrl: './sortable-column.component.html'
providers: [SortService]
})

但是,每列似乎都有自己的服务版本,并且可以同时进行排序(这显然不能按预期工作(。

所以总体问题是:如何将角度服务的一个实例分配给一个(一个(组件(SortableTableDirective(以及匹配SortableColumnComponent组件和同一服务的另一个实例到其他表。

也许更清楚地说明这一点,这就是我想要实现的目标:

-------------------------------------------------------------------------
| page                                                                  |
|                                                                       |
| table 1 - SortableTableDirective - using instance 1 of sortingservice |
|   th 1 - sortablecolumncomponent - using instance 1 of sortingservice |
|   th 2 - sortablecolumncomponent - using instance 1 of sortingservice |
| ....                                                                  |
| table 2 - SortableTableDirective - using instance 2 of sortingservice |
|   th 1 - sortablecolumncomponent - using instance 2 of sortingservice |
|   th 2 - sortablecolumncomponent - using instance 2 of sortingservice |
-------------------------------------------------------------------------

或者有没有办法将某些列组件直接绑定到 table 指令并删除服务?我在这里似乎缺少一个"链接"的概念。

在阅读了更多内容后,我发现了角度文档的另一部分(最后一段(,最终让我走上了正确的轨道:您可以通过将其加载到组件中来限制提供程序范围。然后,它仅对组件及其子组件可用(!正是我在这种情况下所需要的。

当我第一次尝试它时,我犯了一个错误,即在列中加载服务,从而为每个服务提供不同的实例。在 table 指令中加载它效果很好,因为这为表和所有子元素(例如列(提供了一个实例。然后,table 指令的另一个实例加载服务的另一个实例,这允许我彼此独立地对所有表进行排序。

法典:

@Directive({
selector: '[sortable-table]',
providers: [SortService]
})

为了将来帮助某人,现在我们可以使用分层依赖注入

在表组件中,将服务放在 [提供程序] 中,并使用@Host装饰器标记依赖注入。在儿童中,用@SkipSelf标记。

现在,孩子们将忽略他们的"自我"实例,并开始在标有@Host的父项中搜索服务。

请参阅示例:

父母

@Component({
selector: 'table-component',
providers: [TableService],
templateUrl: './table.component.html',
styleUrls: ['./table.component.scss'],
})
export class TableComponent {
constructor(@Host() private tableService: TableService)
}

孩子

@Component({
selector: 'child-component',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
})
export class ChildComponent{
constructor(@SkipSelf() private tableService: TableService)
}

您不应该在组件中提供服务,而是在 AppModule 中提供服务,并通过在构造函数中创建属性来"注入"您的服务。

服务.ts

@Injectable({
providedIn: 'root'
})
export  class MyService {
}

编辑:

组件.ts

@Component ({
selector: '[sortable-column]',
templateUrl: './sortable-column.component.html'
})
constructor(private myService: MyService) {}

appModule.ts

@NgModule({
declarations:[component], 
imports: [YourModules], 
providers: [MyService],
bootstrap: [component]
})
export class AppModule {}

最新更新