Angular 5 创建一个服务的多个实例
Angular 5 create multiple Instances of one Service
我有一个 WebApp 同时显示 3 个虚拟移动设备。
每个设备由一个mobile_container
组成。
我将我的 mobile_container
放在我的根组件中,如下所示:
<div>
<app-mobile-container [fruit]="apple"></app-mobile-container>
<app-mobile-container [fruit]="orange"></app-mobile-container>
<app-mobile-container [fruit]="strawberry"></app-mobile-container>
</div>
fruit
是一个 Inputt,表示他需要访问和显示哪些数据的容器。这工作正常
我创建了一个服务 toggleService
来切换容器中的不同视图,这也很好用。
它看起来像这样:
import { Injectable } from '@angular/core';
@Injectable()
export class ToggleService {
constructor() {
}
tabs: { name: string, visibility: boolean }[] = [
{ "name": "MainView", "visibility": true },
{ "name": "DetailView", "visibility": false },
];
changeTab(index: number) {
//changes View for example to "DetailView"
}
goToPrevTab() {
//changes View for example back to "MainView"
}
}
但是如果我粘贴 3 mobile_containers
并单击 DetailView
-组件,它会更改所有 mobile_containers
中的视图,而不仅仅是单击的视图。这是因为每个容器彼此共享相同的 toggleService
。
如何告诉我的 mobile-containers
创建一个 toggleService 1
、toggleService 2
、toggleService 3
。这样他们就不会访问相同的 toggleView.tabs
?
这是一个问题,你在哪里提供服务,这决定了它在哪里实例化。您可以在组件级别提供。在以下示例中,ReportBindingService 在 ReportContainer 级别实例化。 ReportBindingService 类似于您的 ToggleServiced
@Component({
selector: 'app-report-container',
templateUrl: './report-container.component.html',
styleUrls: ['./report-container.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [ ReportBindingTreeService ]
})
这是我对另一个问题的回答:
该解决方案可能更适合您,因为 ToggleService
独立于任何一个组件或逻辑片段,可以相应地重复使用。您所要做的就是让您的键名独一无二。
这里又是示例代码:
@Injectable()
export class ToggleService {
toggleMap: {[uniqueKey: string]: any} = {};
create(key: string) {
this.toggleMap[key] = null;
}
remove(key: string) {
delete this.toggleMap[key];
}
isShown(key: string): boolean {
return this.toggleMap[key];
}
show(key: string) {
this.toggleMap[key] = true;
}
hide(key: string) {
this.toggleMap[key] = false;
}
}
现在在您的组件中,您可以利用该服务:
@Component({...})
export class MyComponent implements OnInit, OnDestroy {
constructor(public toggleService: ToggleService) {}
ngOnInit() {
this.toggleService.create('componentOne');
this.toggleService.create('componentTwo');
this.toggleService.create('componentThree');
}
// Clean up when parent component is destroyed to save memory
ngOnDestroy() {
this.toggleService.remove('componentOne');
this.toggleService.remove('componentTwo');
this.toggleService.remove('componentThree');
}
}
在模板中:
<button (click)="toggleService.show('componentOne')">Show component 1</button>
<button (click)="toggleService.show('componentTwo')">Show component 2</button>
<button (click)="toggleService.show('componentThree')">Show component 3</button>
<componentOne *ngIf="toggleService.isShown('componentOne')"></componentOne>
<componentTwo *ngIf="toggleService.isShown('componentTwo')"></componentTwo>
<componentThree *ngIf="toggleService.isShown('componentThree')"></componentThree>
我有一个 WebApp 同时显示 3 个虚拟移动设备。
每个设备由一个mobile_container
组成。
我将我的 mobile_container
放在我的根组件中,如下所示:
<div>
<app-mobile-container [fruit]="apple"></app-mobile-container>
<app-mobile-container [fruit]="orange"></app-mobile-container>
<app-mobile-container [fruit]="strawberry"></app-mobile-container>
</div>
fruit
是一个 Inputt,表示他需要访问和显示哪些数据的容器。这工作正常
我创建了一个服务 toggleService
来切换容器中的不同视图,这也很好用。
它看起来像这样:
import { Injectable } from '@angular/core';
@Injectable()
export class ToggleService {
constructor() {
}
tabs: { name: string, visibility: boolean }[] = [
{ "name": "MainView", "visibility": true },
{ "name": "DetailView", "visibility": false },
];
changeTab(index: number) {
//changes View for example to "DetailView"
}
goToPrevTab() {
//changes View for example back to "MainView"
}
}
但是如果我粘贴 3 mobile_containers
并单击 DetailView
-组件,它会更改所有 mobile_containers
中的视图,而不仅仅是单击的视图。这是因为每个容器彼此共享相同的 toggleService
。
如何告诉我的 mobile-containers
创建一个 toggleService 1
、toggleService 2
、toggleService 3
。这样他们就不会访问相同的 toggleView.tabs
?
这是一个问题,你在哪里提供服务,这决定了它在哪里实例化。您可以在组件级别提供。在以下示例中,ReportBindingService 在 ReportContainer 级别实例化。 ReportBindingService 类似于您的 ToggleServiced
@Component({
selector: 'app-report-container',
templateUrl: './report-container.component.html',
styleUrls: ['./report-container.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [ ReportBindingTreeService ]
})
这是我对另一个问题的回答:
该解决方案可能更适合您,因为 ToggleService
独立于任何一个组件或逻辑片段,可以相应地重复使用。您所要做的就是让您的键名独一无二。
这里又是示例代码:
@Injectable()
export class ToggleService {
toggleMap: {[uniqueKey: string]: any} = {};
create(key: string) {
this.toggleMap[key] = null;
}
remove(key: string) {
delete this.toggleMap[key];
}
isShown(key: string): boolean {
return this.toggleMap[key];
}
show(key: string) {
this.toggleMap[key] = true;
}
hide(key: string) {
this.toggleMap[key] = false;
}
}
现在在您的组件中,您可以利用该服务:
@Component({...})
export class MyComponent implements OnInit, OnDestroy {
constructor(public toggleService: ToggleService) {}
ngOnInit() {
this.toggleService.create('componentOne');
this.toggleService.create('componentTwo');
this.toggleService.create('componentThree');
}
// Clean up when parent component is destroyed to save memory
ngOnDestroy() {
this.toggleService.remove('componentOne');
this.toggleService.remove('componentTwo');
this.toggleService.remove('componentThree');
}
}
在模板中:
<button (click)="toggleService.show('componentOne')">Show component 1</button>
<button (click)="toggleService.show('componentTwo')">Show component 2</button>
<button (click)="toggleService.show('componentThree')">Show component 3</button>
<componentOne *ngIf="toggleService.isShown('componentOne')"></componentOne>
<componentTwo *ngIf="toggleService.isShown('componentTwo')"></componentTwo>
<componentThree *ngIf="toggleService.isShown('componentThree')"></componentThree>