Angular event binding not working when using *ngFor - javascript

Right now I have a relatively simple template in my angular controller,
<div class="dropdown-menu" [attr.aria-labelledby]="item.name" *ngIf="item.children">
<button class="dropdown-item" *ngFor="let child of item.children; let last = last" (click)="child.action">{{child.name}} <hr *ngIf="!last"></button>
</div>
However my (click) event binding disappears from the DOM when everything is compiled. If I change the button to a link element and change (click) to [href] it works so.
Appreciate any help, just getting to grips with Angular2 :)
Edit:
I apologise, I had a moment of madness (stupidity)...

You probably mean
(click)="child.action()"
or
(click)="child.action($event)"
otherwise it won't be called.

Related

#click event not triggering alongside element with #blur

I've got a problem when working with VueJS which is kinda getting on my nerfs since I know that it probably relies on something very small but still I'm here trying to get it running for hours.
I'm using a template which should represent a searchbar with the solutions under it. To show the solutions, I'm looping over an object (I'm not done including the filtering of the solutions to that point - wanted to finish this one first). The thing I was trying to do now was filling in the searchbar value with the value I select in the solutions (passing it with a click event). But somehow my click event doesn't trigger.
I've got the following code-snippet:
<template>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">🔍</div>
</div>
<input
type="text"
class="form-control"
#focus="searchFocus = true"
#blur="searchFocus = false"
v-model="searchQuery"
placeholder="Search for vehicles..">
<div class="container p-0">
<div class="dropdown-menu search" v-show="searchFocus">
<a class="dropdown-item bus" href="#"
v-for="vehicle in vehicleObjects"
:key="vehicle.id.key"
v-on:click="setSelectedToQuery(vehicle)">
<span class="ml-4">Bus {{ vehicle.id.name }}
<span class="badge badge-secondary"> {{ vehicle.licenseNumber }}</span>
<span>
</a>
</div>
</div>
</div>
</template>
Am I missing something quite obvious? How can I get the click-event running/triggering?
Thanks in advance
Best Regards
There are few things "off" I'll list them by level of impact
#blur fires before click, essentially invalidating #click
anchors <a ...> need to prevent redirect. You can use #click.prevent="... to prevent event propagation, or use another element, since you don't have href defined anyway.
one of your span elements is not closed (<span> instead of </span at the end)
To handle #blur blocking #click, you could use #mousedown instead of #click, since it executes first.
Maybe it's the solution: close your last span
Click work for me: https://codesandbox.io/s/morning-browser-fgftf

AngularJS - ngShow/ngSwitch/ngIf - Two elements flicker

So I have a two elements that are rendered inside an ng-repeat, when I click a button that does a toggle, for a brief second both elements get shown.
I have tried various things, ngIf, ngShow, ngSwitch and ngCloak and nothing seems to work.
Here is a code sample:
<div data-ng-repeat="item in view.myModel.items">
<div class="row">
<a ng-hide="item.link" class="btn ng-cloak"
ng-click="view.getLink($index)">Get Link</a>
<a ng-show="item.link" class="btn ng-cloak"
data-ng-href="{{item.link}}" download>Download</a>
</div>
</div>
So here is the problem, on load I only see the 'Get Link' button which is fine.
As soon as I click it, it makes a http call and sets the 'items.link' value, which is where the problem happens. At that moment both buttons are shown together.
Then correctly just the download button shows.
Here is the http call if your interested:
/**
* Get a link
*/
function getLink(idx) {
Linker
.getLink(idx)
.then(onGotLink);
function onGotLink(link) {
myModel.items[idx].link = link.url;
}
}
Any ideas?
So credit to user1620220 who pointed it out. The issue is ng-animate is running that is causing the ng-hide-animate to trigger causing that slight flicker.
You can turn off ng-animate, or use CSS to turn of 'transition' if you only want to partially disable it is.

Cascading expression in AngularJS works with ng-show but not with ng-if

The following block of code work if I use ng-show to display sections but not with the desired ng-if
<div ng-controller="nullController">
<button ng-click="p = 1">click to reveal next</button>
</div>
<div ng-show="$$prevSibling.p == 1" ng-controller="nullController">
<div>Appears based on previous sibling state</div>
<button ng-click="p = 1">click to reveal next</button>
</div>
<div ng-show="$$prevSibling.p == 1" ng-controller="nullController">
<div>Appears based on previous sibling state</div>
<button ng-click="p = 1">click to reveal next</button>
</div>
See in Plunker ng-show
See in Plunker ng-if
UPDATE: someone pointed out that the version of the angularjs lib in the plank did not have ng-if. Now I have updated to use 1.2.x the problem however did not go away.
You are using angularjs 1.0.1 !
ng-if didn't exist in this old version yet.
Only the versions above 1.1.5 handle the ng-if directive.
You really should rather choose this version (the latest stable one) for your plunkr for instance:
<script data-require="angular.js#1.2.16" data-semver="1.2.16" src="https://code.angularjs.org/1.2.16/angular.js"></script>
Here's a more official data to show that ngIf was available since 1.1.5.
Furthermore, pay attention that ngIf creates a new child scope.
Indeed, it needs this mechanism in order to achieve the delete of the component from the DOM.
ng-show does not need it since it simply hide the content.
Thus, $$prevSibling would not target the expected scope, since called from a deeper scope in the scopes' hierarchy.

Is it possible to access a function in a directive from a view?

I'm fairly new to AngularJS and trying to learn by doing.
There is a function in a directive I'm looking to access from the view. What I have in my HTML file is
<div collapse class="collapsed" ng-click="toggle()" ></div>
What's going on there is the toggle() function should be called on click and change the class to expanded, effectively changing the background image described in the CSS. toggle() is inside the collapse directive.
It doesn't seem to be accessing it though and I'm not sure why. Is there another way to do this or actually access said directive from the view? Could you explain why it's not accessing it?
Could this question possibly help? 15672709, it leads to this fiddle and goes beyond in case you nest your directives like below:
<div ng-controller="MyCtrl">
<div screen>
<div component>
<div widget>
<button ng-click="widgetIt()">Woo Hoo</button>
</div>
</div>
</div>
</div>

How to expand DIVs the "angular way" (using angular masonry)

I'm trying to expand a DIV element on my angular layout. I'm using angular-masonry to give a mason-style to my layout, but now I need to expand those boxes on click. I've tried a lot of stuff, but it kept overlapping my others elements. Soon figured out that I'll have to write it the "angular way" so I don't run into DOM manipulation conflicts.
Here's my code:
<div class="row" masonry>
<div
class="masonry-brick item-component col-sm-4 col-md-4"
ng-repeat="component in components.components | filter : components.filterByFilter | filter : searchText"
ng-click=" // expand #expandable // "
>
<div class="component-wrapper">
<div class="component">
<img ng-src="#{{ component.thumb }}"/>
</div>
<div class="component">
#{{ component.name_en }}
</div>
</div>
<div id="expandable" class="expand-me codes-wrapper">
<p>XXX</p>
<p>YYY</p>
<p>ZZZ</p>
</div>
</div>
</div>
Here's what I want to accomplish in the "angular way": http://codepen.io/desandro/pen/daKBo
In your example (http://codepen.io/desandro/pen/daKBo) if you click on an element there are two things that will be done:
(1) the style of the clicked item is changed
(2) the function masonry is called on the container element that keeps the divs.
I can't see such a function in angular-masonry pre builded. So i'll guess you have to do this by your self. Here are some hints how to solve this (i havn't try it in real)
Bind a function to ng-click. In this function set a state to the current component. This state shoud be used to toggle the css-class of the element. you can use ng-class for this.
The second part is little bit more complex. I would suggest write a direcive 'masonry-change-listener' and bind it to the element that is bound to the same element with the directive masonry. If you click on a component $emit an event, that something has changed. In the directive 'masonry-change-listener' listen to this event. if this event fires you have to call $element.masonry.apply($element) in the link function.

Categories