After_8
After_8

Reputation: 329

Angular 5 create multiple Instances of one Service

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

Answers (2)

Lansana Camara
Lansana Camara

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

jeff
jeff

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

Related Questions