I have an Ember component which is essentially a panel. There can be multiple instances of this panel on a page, but only one can be "active" at any given time. Each instance of the component must be aware if any of the other panels become "active" so they can remove their "active" state. I would really rather not move the JavaScript to make this happen to a parent component. Instead, I would like to keep it within this component. In Angular, I used to use a static variable to do this. What is best way to do this in Ember?
What is the best way for all instances of an Ember component to share a variable?
379 Views Asked by soultrust At
2
There are 2 best solutions below
1
On
@arne.b 's anwser sums it pretty well, the best way of handling component's state with common parent data, but if you are dead serious about not using a parent component there is kind of way to get it done.
Example:
import Ember from 'ember';
export default Ember.Component.extend({
sharedObject: {},
sharedArray: [],
});
In the above component you can use sharedObject or sharedArray to exchange state with multiple instances of the component. Any changes in the object or array will be reflected to all the instances of the same component.
A sample Ember twiddle.
Do you want to avoid having the parent component dealing with anything related to panel "activity"? If so, why?* If not:
Ember automatically gives each component's tag (unless it's a tagless component) an id that is accessible from the js code as
elementId. You could create a propertyactivePanelIdon the parent component and pass it to all panels:{{pa-nel activePanelId=activePanelId}}and then check in each panelor use it in the js code:
If the panel becomes active by an action related to itself (e.g. clicking on it), just set
activePanelIdto theelementIdin the respective action - since the propertyactivePanelIdexists only once on the parent component, all other panels to which it is passed will take note.If using the
elementIdfeels to hacky, you might as well give each panel a distinct name and store theactivePanelNamein the calling component.*If you really do not want the property in the parent component, you could move it to a service that you then inject into the panel components, but I cannot yet imagine a good reason for preferring that.