Reputation: 329
I have a WebApp showing 3 virtual mobile devices at the same time.
Each device consists of a mobile_container
.
I put my mobile_container
in my root-component like this:
<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
is an Inputt which says the container which data he needs to access and display. This works fine
I created a Service toggleService
to toggle the different Views in on of the Containers this works great too.
It looks like this:
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"
}
}
But if i paste 3 mobile_containers
and click for example the DetailView
-Component it changes the View in all mobile_containers
and not only in the clicked one. This is because every container shares the same toggleService
with each other.
How can i tell my mobile-containers
to create a toggleService 1
, toggleService 2
, toggleService 3
. So that they don´t access the same toggleView.tabs
?
Upvotes: 3
Views: 13517
Reputation: 9871
Here is my answer from another question: https://stackoverflow.com/a/46797196/4749297
That solution may work better for you as the ToggleService
is independent of any one component or piece of logic and can be re-used accordingly. All you have to do is make your key names unique.
Here is the example code again:
@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;
}
}
Now in your component, you can leverage the service:
@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');
}
}
In the template:
<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>
Upvotes: 1
Reputation: 3327
It's a question where do you PROVIDE the service, which determines where it is instanced. You can provide at a component level. In the following example, ReportBindingService is instanced at the ReportContainer level. The ReportBindingService is analagous to your ToggleServiced
@Component({
selector: 'app-report-container',
templateUrl: './report-container.component.html',
styleUrls: ['./report-container.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [ ReportBindingTreeService ]
})
Upvotes: 17