watch a template in angularjs - angularjs

I have a full template
I would like to put a watch on this tempalte, in order to call a function in the controller any time something is clicked inside that template.
I know I have to use a watch (I believe I do) but I don't understand how to to the connection between the full template and the watch.

To do this just add the ng-click directive to your parent element so that every click inside that element evaluates the expression inside the ng-click attribute:
<div class="parent" ng-click="callFunction()">
<div>Hello World</div>
</div>
If you want some clicks inside the parent element to not trigger the parent ng-click you can add $event.stopPropagation() to stop event propagation:
<div class="parent" ng-click="callFunction()">
<div>Clicking here will call parent callFunction()</div>
<div ng-click="$event.stopPropagation();callAnotherFunction();">
Clicking here won´t call parent´s callFunction()
</div>
</div>

Related

ng-keyup firing but not reading properly when used with an ng-if inside a directive template

I have a directive and it works fine in a way such that when I type something the search() scope function inside my directive fires and sets $scope.query with the input text.
here is the directive template
<div class="container">
<div class="system-filter-header">
<div class="no-gutter">
<div class="system-search-wrapper search-wrapper-width">
<i ng-click="search($evt)" class="fa fa-search"></i>
<input type="text" ng-keyup=search($evt) class="search pull-left suggesstions-styles"
ng-model="query" ng-attr-placeholder="Search...">
</div>
</div>
</div>
</div>
here is the scope function which gets triggered
$scope.search = function() {
console.log($scope.query.length)
}
But when I used an ng-if="true" in first line of template (true used for generalizing only, I want to do a different conditional check inside ng-if) such that,
<div class="container" ng-if="true">
still the search gets triggered but the console.log gives always 0 and it doesn't seem to update the $scope.query value as it stays as $scope.query = ''
throughout the typing.
EDIT
Here is a an example codepen with almost similar behaviour. The problem is with the searchBox directive and I have added ng-if=true to the template but searching doesn't work. When I remove the ng-if searching works fine.
Any reason for this?
Rule of thumb in AngularJS: your ng-model should always include a dot. Otherwise AngularJS directives that create child scopes (like ng-if or ng-repeat) will create a duplicate property on that child scope instead of the parent scope. Following the controllerAs convention completely mitigates this behavior.

Prevent triggering Angular Material md-swipe-left/md-swipe-right directive's function on parent element

I have a parent element that fills 100% of page height and several child elements inside it. Swipe-right on the parent toggles side menu, but I want to prevent this function and trigger childAction() when I swipe-right on it's child.
<div id="parent" md-swipe-right="toggleSideMenu()">
<div id="child" md-swipe-right="childAction()">
....
</div>
</div>
The md-swipe-right like all other event directives provides $event as a local.1
In your HTML include $event as an argument to your function.
<div id="parent" md-swipe-right="toggleSideMenu()">
<div id="child" md-swipe-right="childAction($event)">
....
</div>
</div>
In your controller invoke the stopPropagation() function.
$scope.childAction = function (event) {
event.stopPropagation();
});
For more information on $event see, AngularJS Developer Guide -- expressions -- $event

using ng elements outside of ng-controller

I am inexperienced with angular.
I am using angular to create a series of nested divs (a form) on a webpage. The top div has ng-controller="controllername" as an attribute. Within the nested divs is a div with ng-show="showvar" as an attribute.
It looks like this.
<div class="page">
<div ng-controller="controllername">
<div ng-show="showvar">Hidden Stuff</div>
</div>
</div>
When I perform functions on showvar to make it true, the div appears (and disappears when false) as intended.
I also have a completely separate div 'outside' the the original nest of divs with the ng-controller attribute. As such, there is no ng-controller attribute in this seperate hierarchy BUT I have nested another div inside with the ng-show="showvar" attribute.
Updated HTML structure is as such
<div class="page">
<div ng-controller="controllername">
<div ng-show="showvar">Hidden Stuff</div>
</div>
<div class="seperate">
<div ng-show="showvar">More Hidden Stuff</div>
</div>
</div>
When the page loads, both divs with ng-show="showvar" in the separate nests are hidden as ng-hide has been appended by angular. When I perform functions on showvar after the page load to make it true, only the div within the ng-controller div gets shown.
I (think I) understand this is because the ng elements are evaluated at page load (and appended with ng-hide, even outside the controller?) but only the ng elements within the div with the ng-controller attribute are evaluated when functions are performed after page load. Is this correct?
How can I get the other ng-show to be evaluate 'outside' of the ng-controller div?
I was thinking one option is to append ng-controller to the overall 'page' div instead of the nested div. But what other options do I have?
EDIT: I also tried simply adding ng-controller="controllername" to the separate div. I guess angular 'ignores' the duplicate ng-controller div?
The problem your facing is that the showvar resides in your controller's scope, your second usage of the showvar is not within that scope.
What you need to do is make sure the variable is available where needed.
Say you add the variable to the parentController (you don't have one in your example so I'll add one)
<div class="page" ng-controller="parentController">
<div ng-controller="controllername">
<div ng-show="showvar">Hidden Stuff</div>
</div>
<div class="seperate">
<div ng-show="showvar">More Hidden Stuff</div>
</div>
</div>
app.controller('ParentController', function($scope){
$scope.showvar = false;
});
problem with this is when you set showvar to true within your controllername controller it will set it in the innerscope and not the outer. When making sure you have the right scope by accessing it through another object you should be safe.
So try it like this:
<div class="page" ng-controller="parentController">
<div ng-controller="controllername">
<div ng-show="obj.showvar">Hidden Stuff</div>
</div>
<div class="seperate">
<div ng-show="obj.showvar">More Hidden Stuff</div>
</div>
</div>
app.controller('ParentController', function($scope){
$scope.obj = {
showvar: false
}
});
Quick demo
Your issue here is that you ended with 2 "showvar" variables: one within the "controllername" scope and another one on the app scope (as you have a ng-app declaration somewhere in your html parent of the "page" div).
When you load your page, you get the value of "showvar" in the controller scope for the first div, and for the "separate" one, you get the "showvar" variable in the app scope, which doesn't exist, therefore it is resolved to "false" (even though angular declares it for you in your app scope and you can even modify its value later).
When you change the value of "showvar" in the controller scope, it doesn't change the one in the app scope, making the "separate" div stay hidden forever =)

Render a directive from a controller

I've built a directive <playlist> which calls my custom service to return and then display a list of videos. So far so good. However, I don't want this directive to render and call my API until the user clicks on a link elsewhere on the page.
How can I have a link outside of the directive trigger the rendering of the <playlist> item? I looked for some sort of onShow event to no avail.
You can use the ng-if directive to keep your directive out of the DOM until the link is clicked. So your HTML would looks something like this:
<div ng-if="showPlaylist">
<playlist />
</div>
Then you would just set showPlaylist to true when you want it to show/render.
I was able to figure this out based on dnc253's feedback.
Toggle Playlist
<div ng-if="showPlaylist != undefined">
<playlist ng-show="showPlaylist"></playlist>
</div>
On initial page load <playlist> is hidden and not rendered. Clicking the link renders <playlist>. Subsequent clicks toggle the ng-show attribute and so the scope is not reset.

Sub directive triggers parent click-event in Angular.js

i got the following structure:
<div directiveA>
<a href="" directiveB>
</div>
Both directives got an onclick event. The problem is, that if a click on directiveB is performed, a click on directiveA is triggered as well.
How can i prevent this?
Thanks
In the directiveB on the click directive do this this
ng-click=doSomething();$event.stopPropagation()
There is an $event object available for all DOM events supported by angular.

Resources