I have two components on one page: Component1 and Component2. Inside each of those is Component3. Obviously each Component 3 is its own instantiation of the component. However, I would like a global variable between the two. I'm creating a side-by-side comparison of some data, and would like an accordion to work, so when I click to expand the accordion on one Component 3, the other one also opens. I have been searching for hours and cannot find a resolution to this.
What I want is, for instance:
(click) = "changeGlobalVar()"
to change the global variable. Then I would like to have
*ngIf="globalVar"
That way, the ngIf
works on both Component 3, no matter which one I click on.
Could someone please help me out? I've been searching for an answer to this for hours.
Here's what my service code looks like but doesn't seem to be working:
import {Injectable} from '@angular/core';
@Injectable()
export class DropDownService {
public _acDropDownToggle: boolean;
setValue(val) {
this._acDropDownToggle = val;
}
getValue() {
return this._acDropDownToggle;
}
}
So you are half way there and you need just a few clarifications on how to leverage a service. The service you create should only be inserted as a "provider" in your main component. All child components will use the service as a "Dependency injection", this means the child components will request the service in their constructor method arguments.
For example your primary component will look like this
import {componentStateService} from './componentState.service'
import {ComponentOne} from './component1'
import {ComponentTwo} from './component2'
@Component({
selector: 'test-app',
template : `...`,
providers: [componentStateService],<----
directives: [ComponentOne,ComponentTwo]
})
export class AppComponent {
constructor(){}
}
Then the child components (component-one,component-two in my plunker example. For your code you would only apply this to your third component), will have the service injected in through their constructors.
import {componentStateService} from './componentState.service'
@Component({
selector: 'component-one',
template : `...`
})
export class ComponentOne extends OnInit {
private _componentVisible:boolean;
constructor(private _componentStateService:componentStateService){<----
this._componentVisible = true;
}
}
This will ensure that only one instance of your service is created.
The next step is to add an "observable" to your service and then "subscribe" to that observable in your child components.
Here is a plunker that demonstrates exactly what you are looking for. You will need to use the RxJS modules. The plunker shows you how to add this if you are using SystemJS. If you are using the TypeScript compiler to transpile your .ts to .js, you will also need to install RxJS through npm(In the plunker example SystemJS is using a module to transpile).
A good tutorial on Angular 2 Observables can be found here. The tutorial leverages a lot more features than what I use in the plunker but that should be enough to get you started.
Since the variable ind DropDownService is to be shared between two instances of component 3, the best place to instantiate it would be in the page component.Page Component will be the lowest common ancestor of the two component3 instances
Assuming your component tree is like this :-
PageComponent
/ \
/ \
Component1 Component2
/ \
/ \
Component3 Component3
The best place to provide DropDownService in the providers array will be in the Component Decorator of PageComponent. You should then just inject it in the constructor of Component3. If you specify the service in provider of any of the child components of the Pagecomponent, a new instance will be created again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With