0

I am trying to open an Angular accordian in the header.html by clicking a button which is in the body.html. Essentially triggering an event in one view from a completely different view. Does anyone have any idea how to do this in Angular?

LordTribual
  • 4,219
  • 2
  • 28
  • 38
user791134
  • 203
  • 1
  • 5
  • 16
  • 1
    You can broadcast an event from the controller for the HTML page with the button to the controller for the page with the dropdown. Have a look [here](http://stackoverflow.com/questions/14502006/working-with-scope-emit-and-on). – Tim Biegeleisen May 28 '16 at 09:46
  • Or just set a flag in $rootScope. – dfsq May 28 '16 at 09:47
  • this has been answered so many times on stackoverflow. I know because I've answered about 3 of them – Callum Linington May 28 '16 at 09:47
  • $rootScope flag, shared service or broadcasted event. – dfsq May 28 '16 at 09:48
  • Does my answer help you? – LordTribual May 28 '16 at 12:42
  • LordTribual. Sorry for the late response. Yes it did. I have marked it as the answer. Btw thank you to all of you for your input! I am now trying to figure out how to get a $timeout function to work to close it. Will make a new question. Thank you again. – user791134 May 30 '16 at 06:06
  • Let me know if I can help you there as well. – LordTribual May 30 '16 at 08:07
  • Solved. I appreciate it though. http://stackoverflow.com/questions/37519009/issues-with-getting-timeout-function-to-work/37519398?noredirect=1#comment62533219_37519398 – user791134 May 30 '16 at 21:18

1 Answers1

0

What you can do is using events to let your accordion directive know that something happend or use a shared service. Considering the performance, it does not make a huge difference, but only if you use $emit instead of $broadcast since the event fired via $emit bubbles up your scope hierarchy and $broadcast sends the event down. Also make sure to fire the event on the $rootScope, so it won't event bubble up anymore.

So you in case you want to use events for you could have a method on your component that fires the event via $emit on the $rootScope as follows:

function openAccordion() {
    $rootScope.$emit('on-accordion-open', null);
}

You could then use this in your view, e.g. in body.html. Remember that function above is part of another directive / component or controller.

<button ng-click="vm.openAccordion()">Open Accordion</button>

Also note that I assume you are using controllerAs syntax (set to vm).

In your accordion directive you can then hook up listeners to several events for example the on-accordion-open:

$rootScope.$on('on-accordion-open', function() {
    // Open the accordion
});

The other soltuion is to use a shared service. In this case I would create a AccordionServce that is aware of all instances of accordions. The service could look like this:

angular.module('myApp').service('AccordionService', function() {
   var accordions = {};

   this.addAccordion = function(name, accordion) {
       accordions[name] = accordion;
   };

   this.removeAccordion = function(name) {
       delete accordions[name];
   };

   this.getAccordion = function(name) {
       return accordions[name];
   };
});

In your accordion's controller you then add the accordion to the AccordionService via

accordionService.addAccordion('myAccordion', this);

The this in the snippet above is refering to the accordion controller. Thats important because if you then get an accordion in your component in the body.html, you'll get the controller instance and can call methods like open.

So in your body component you can then inject the AccordionService and get the accordion to call a method:

accordionService.getAccordion('myAccordion').open();

Make sure to define open on the accordion's controller.

LordTribual
  • 4,219
  • 2
  • 28
  • 38