4

With Angularjs, you can bind an event to a dom element like this:

<div ng-controller="SampleController">
    <a ng-click="showTheHiddenDiv()">Show the hidden div</a>

    <div ng-show="showHiddenDiv">
        hidden content
    </div>
</div>

My question: is it possible to attach an event handler function like this from outside the controller, like this?

<a ng-click="showTheHiddenDiv()">Show the hidden div</a>

<div ng-controller="SampleController">
    <div ng-show="showHiddenDiv">
        hidden content
    </div>
</div>

This does not work, I'm wondering if there is a special way to access the showTheHiddenDiv() function. I know i could just wrap everything in another container and make that the controller scope, but I'm wondering if its possible to do it this way.

Thanks!

4
  • what is "outside of controller"? in terms of scope, etc. Commented Jun 19, 2014 at 4:37
  • I mean the event target dom element that has the ng-click directive is outside of the ng-controller dom element Commented Jun 19, 2014 at 4:38
  • right, the showTheHiddenDiv should be then defined on the other scope... Commented Jun 19, 2014 at 4:39
  • I am not sure what you are asking, but if you want to have a flag showHiddenDiv that could be changed by your ng-click outside the scope that your ng-controller creates, just try using $parent like this: <div ng-show="$parent.showHiddenDiv"> Commented Jun 19, 2014 at 5:18

2 Answers 2

3

Think bindings. You want to introduce a variable on the scope that the view (ng-click and inner div can bind to). It would make sense to make this variable a Boolean so that when it changes, it will update the views.

Start by creating a showDiv variable on the scope, and updating it when the anchor link is clicked:

<div ng-controller="SampleController">
    <a href="#" ng-click="showDiv = !showDiv">Show the hidden div</a>

    <div ng-show="showDiv">
        hidden content
    </div>
</div>

When the link is clicked, it will toggle 'showDiv' which is saved on the scope of SampleController. Since, the ng-show directive on the inner div is bound to 'showDiv' (the same showDiv that is on the SampleController's scope), it will automatically show and hide based on the value of 'showDiv'.

[EDIT]

I failed to answer the original question, so I'll try again.

It is certainly possible to define a scope variable that is outside SampleController and bind it to the view within an inner controller:

<a href="#" ng-click="showDiv = !showDiv">Show the hidden div</a>

<div ng-controller="SampleController">

    <div ng-show="showDiv">
        hidden content
    </div>
</div>

This works because of scope inheritance. When you have scope inheritance, the child scope inherits the scope variables from the parent scope. In the above example, you have the scope of SampleController (the child scope) which inherits from the scope of the outside controller (the parent scope). If there is no parent controller, then the parent scope is just the root scope. The important point is that child scope inherits from parent scope, and inherits all its scope variables.

In the example above, ng-show is bound to showDiv, but it hasn't actually been assigned to a scope variable in any scope (yet). So initially, 'showDiv' is undefined but it remains hidden because in angular, undefined is treated as false when evaluated. Once you click the link, then showDiv is assigned !showDiv. It is at this point that the scope variable 'showDiv' is created, and since the assignment happens outside of SampleController, the scope variable is created in the parent scope - in this case, the root scope.

Since showDiv is bound to the same scope variable in both the anchor link and the ng-show directive, any changes to the scope variable 'showDiv' (such as clicking the link), will propagate to all views that are bound to it (the div that contains the hidden content).

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the help - I think this is pretty much what I have in my top example though, with the exception of doing the evaluation directly inline instead of calling a function. My question is about the ability to access the showDiv variable when clicking an element that is outside of the ng-controller="SampleController" scope.
The short answer is yes. I updated my post with a full explanation.
Thank you, that is a really good explanation and it works. I think my original problem must have been that I wasn't setting up the root scope correctly (no ng-app directive). Just starting w/ angular, so this is very helpful.
0

You can always use a service and a directive to share a value between different scopes.

 app.service('SharedService', function(){
   this.showHiddenDiv = false;
 });

app.directive('showDiv', function(SharedService){

  return {
    restrict: 'AC',
    link : function(scope, element, attr) {
       scope.showHiddenDiv = SharedService.showHiddenDiv;
       scope.toggleDiv = function(){
         SharedService.showHiddenDiv = SharedService.showHiddenDiv ? false : true;
       }
    }
  }
})

html:

<a ng-click="toggleDiv()" show-div>Show the hidden div</a>

<div ng-controller="SampleController">
    <div ng-show="showHiddenDiv" show-div>
        hidden content
    </div>
</div>

As a side note, any time you're trying to manipulate the DOM, you should be doing so in a directive, that's the angular way!

11 Comments

I think the ng-click handler will use a different showHiddenDiv than the ng-show directive inside the element with ng-controller
Get rid of showHiddenDiv from your controller all together.
thank you, i'm new to angular so your advice is appreciated. Question; where do you put the code that houses the app.directive call? Is there a convention for this? So far just been using controller files like /js/SampleController.js
ng-controller directive creates a new scope (docs.angularjs.org/api/ng/directive/ngController) so ng-show="showHiddenDiv" will use a different scope than the ng-click.
I accepted pixelbits answer because it seems a more succinct answer to my original question, but upvoted for getting me looking at directives. Thanks again!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.