Creating a function for triggering CSS animation in AngularJS - angularjs

What is the best way to trigger/activate CSS animation from within a function in AngularJS?
In my case, I have a slide, which has one label <> and a button <>.
When a user clicks on the button, I'm calling an API, and on failure case, I need to animate the label.
One way will be to use ng-class directive. In which creating a scope variable, and set and reset value using $timeout service.
But I'm thinking of making a function something like playAnimation() and call this function which will trigger the animation.
What will be the steps for doing so in anularjs?
I'm using angularjs version 1.5.

I don't think creating a function would be better than using ng-class as you initially suggested. You could them benefit from Angular's animation classes (e.g. ng-enter, ng-leave etc), saving code in your scripts.

Related

In angular ng-show without ng-click?

So, I'd like to show a div when a flag is set to true. I've been able to achieve this with ng-show by toggling the value of the flag with a button click.
However, I'd like to use ng-show when that flag is changed by something other than a button click. There is a stream of events that I'm taking in from my backend service, and one of the events would flip this flag, but ng-show never seems to fire off unless I trigger it specifically with a button. Right now, the only way that I can get that effect that I want is just by directly calling **document.getElementById().hidden = true/false.**
Any ideas? Thank you!
Maybe I'm misinterpreting your use case but it seems very simple: just use a variable in your controller / component and reference that variable in your ng-show.
// in your html
ng-show="myFlag"
// in your js
$scope.myFlag = true;
It may be a little more complicated depending on how you are using that backend service.

Invoking a callback before or after showing a popover using angular-ui-bootstrap

I have a very simple code snipper in my page where I have a span. Hovering over this span displays a popover for which I am using angular-ui-bootstrap.
<span uib-popover="This is a popover from Akhilesh"
ng-mouseenter="vm.logToConsole('I am trying hard...')"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Basically I have written a function which makes and API call when the user hovers over this span. The problem here is that let's say I have 10 span tags one below the other and the user quickly moves from 1st span to 10th span (in the process hovering over all 8 spans in between), the API call will get triggered for all the spans. This is what I do not intend to have.
Any idea how can I implement the debounce functionality here?
Use a delay, like one second, after the mouse enters the region, then if the mouse hasn't entered another area, make the API call.
The popover-is-open attribute was added under the 0.13.4 release that can be used to watch the state of your popover like so:
<span uib-popover="This is a popover from Akhilesh"
popover-is-open="vm.isOpen"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Then in your controller:
$scope.$watch('isOpen', function() { });
But if you are just trying to keep the popovers from opening so quickly, consider using the popover-open-delay attribute.
Depending on your use, I found the best method is to simply add ng-mouseover, ng-click etc to the element and define a function to be called.
You can even create a variable and attach it to that objects scope on the fly to keep track of the state (open close).
Kind of hacky, but there is currently no way to define a function that is called on open and on close within ui-bootstrap popover.

Need to $watch property from within an accordion (Angular-UI) but won't work

We're building a page with Angular, Angular-UI and UI-Bootstrap. The last one includes a directive for accordion, which simplifies a quite repetitive task of building up an accordion and an accordion group.
We, however, must watch for changes from an input inside that accordion. Problem is that the accordion has a child scope and it work work.
Here's a sample from Plunker (open the accordion by clicking on "Just a heading").
Is it possible to track changes into that input?
Try to $emit a custom event. It should bubble up to your scope. Worst case you should be able to listen to that event on the $rootScope
so something like :
$scope.$emit('input:change',{DATA});
on the accordion controller
and
$scope.$on('input:change'),function(data){
//do stuff with the change in input
})

AngularJS - Do I need to call $apply if no model is changed?

Greetings Overflowers,
If I am changing an HTML native attribute (say a division's class) inside an event handler, do I need to wrap it with a call to $apply? In other words, are these native attributes watchable?
EXAMPLE:
I am doing a custom directive inside which I am modifying the element's classes for styling on certain events like mouse enter, but no modification to the scope (or model).
I am wondering if I need to surround this logic with a call to $apply just in case there is a $watch on these element's class attribute? Are these $watches possible using angularjs? My custom directive will be used by other programmers.
Kind regards
Any thing that Angular doesn't know about should be inside an $apply if you want bindings to be updated etc...
So no, this native attributes are not watchable if you manually change the DOM and it's not part of a user event or Angular's service event (like $http)

Is their a better way for a controller to 'call' a directive

I have a directive that creates and manages a bootstrap modal dialog.
Currently I have the directive watch a boolean held on the controller. The controller can then set this to true to have the modal dialog display.
This seems kinda messy. Is there a better way?
The directive in action:
<modal trigger="shouldDisplayModal" title="{{modalTitle}}"
message="{{modalMessage}}" positiveclick="okClicked()"
negativeclick="closed()"
positivelabel="Ok" negativelabel="Cancel"/>
The watch in the controller of the directive:
// watch the trigger value. expected to be boolean
$scope.$watch('trigger',function(newValue, oldValue){
if (newValue)
{
// enable any disabled buttons
modalElem.find('button').removeClass('disabled');
// show the dialog
modalElem.modal('show');
}
else
{
// hide the dialog
modalElem.modal('hide');
}
});
Here is a working example: http://jsfiddle.net/rabidgremlin/Ya96z/31/
UPDATE: Here is a fixed up example that corrects some issues with multiple directives on a page: http://jsfiddle.net/rabidgremlin/sjbCJ/1/
I was going to suggest using ng-show inside your directive's template (this what the dialog component on the directive page does, along with a visible attribute that is just like your trigger attribute), but then I saw that you also need to enable some buttons before modifying the visibility.
So, I think what you have is fine, and I don't see it as messy. Either your directive has to $watch for something, or you could create the dialog when an event happens -- this seems to be what the $dialog service does that #pkozlowski mentioned in the comments. The latter would not need a trigger attribute.
I blogged about working with angular and bootstrap modals just a couple weeks ago.
My solution involves a service, all of the hide/show magic for the modal is handled by bootstrap's javascript, and angular just worries about the data.
http://willvincent.com/blog/angularjs-and-twitter-bootstrap-playing-nicely

Resources