Custom directives not active in nested views when using ui-router - javascript

I was working on an angular app (phonegap+ionic+angular), I had written a custom directive which registered an event listener for that element (which would activate iScroll for that element on load event). The directive was working fine when all the view was in index.html. I decided to refactor the code and intorduced nested views and routes using ui-router. Now the directive seems to be not functioning. I tried making a mock directive that would just console.log() and nothing happened.
Am I missing something here?
Any kind of help or lead would be highly appreciated.
Thanks.

I have found the problem and the solution to my problem. I'm posting here so that others facing similar problems could benefit from it.
Turns out, since my directive did not run because it was executed before the sub view was loaded. So I solved the problem by just adding a
scope.$watch("$viewContentLoaded") wrapper around my directive's codes and it started working.

Related

AngularJS ng-bind-html and components

I'm using AngularJS ver. 1.6.8.
I have a component I have built called icons. To incorporate it in a page I just add <icons></icons> and the component is inserted into the page.
Now I have a scope variable that holds html, and part of that html is the previously mentioned code <icons></icons>.
When I use ng-bind-html it doesn't compile the component and instead just shows <icons></icons> as text.
I have tried using angular-bind-html-compile (link) but that didn't help.
All of the solutions I found seem to support angular pre made directives and not newly formed components.
Happy to hear of any possible solutions.
Did you do the following on your scope variable which holds the html code? This is a common mistake.
$scope.trustAsHtml('<div>....')
But as mentioned before, without your code it is hard to figure out the problem.

Trigger jQuery function after page has loaded in AngularJS

I just started learning AngularJS and I'm not really familiar with the terminologies in AngularJS yet. Here's my concern, I created a Loading Animation that shows up when I go to pages, but then I want to stop the Loading Animation as soon as all the contents of the pages has loaded. It's fairly easy to do in plain jQuery since I can just trigger $(window).load() but it doesn't seem to work in angular. $(document).ready() seems to work but that's not what I actually need since it gets triggered even though the images are not finished loading yet. I already tried $scope.init inside my controller as well as $window.onload inside my controller but I still can't make it work.
Hotfix answer
Actually you do not need to wait for any of these events in angular.
Just use $().. in your angular controller - the site was already loaded. (similar to the window.load() event. In case jquery does not find the html elements please try to wrap it with $timeout( function() { ... } );
Recommendation
Please do not! There are angular ways to animate stuff which fits better than crazy $('#id'). logic. This will break in growing applications.
I would recommend you forget about jQuery when you are working on AngularJS application. So figure out how to work everything out in AngularJS way - move all jQuery logic that you have to angular controller and avoid direct DOM manipulation (jQuery way).
Also, there's a good tutorial online if you are moving to AngularJS from jQuery:
https://gabrieleromanato.name/introduction-to-angularjs-for-jquery-developers
If you need a solution for switching pages go with ui-router - it will give you even more flexibility with loading pages and resolving properties for different pages:
https://github.com/angular-ui/ui-router
And in this particular case you can use simple boolean property on $scope and show preloader div based on that:
<div ng-show="showOverlay" class="loader" />
then inside your controller you could put something like:
$scope.showOverlay = true;
and then after your page logic is loaded and promises are resolved you could just hide that preloader with:
$scope.showOverlay = false;
To illustrate I created simple fiddle with preloader for you. Also keep in mind there are tons of different ways of implementing this but this is simple one that should work for almost any case:
https://jsfiddle.net/pegla/ng1mn8qp/3/
There's also one answer here on stack overflow that could help you:
How to execute angular controller function on page load?

ng-show does not work correctly with ng-animate

When animate module is loaded then ng-show does not work. Default value for ng-show expression is false, but element is still shown and class ng-hide is missing. If i unload animate module, then it works fine.
<script>
var app=angular.module('app', ['ngRoute','ngCookies','infinite-scroll','ui.mask','ngAnimate']);
</script>
I have the same problem, it's probably a timing issue, but there is a workaround.
in short, there is some collision between a class defined in the "class" attribute with interpolation, and other directives on the same element trying to add another class. removing the class="{{::item.customClass}}" gets ng-class and ng-show directives to work fine.
I couldn't reproduce it on a plunker, probably because of the large amount of components involved. we use $templateCache service, ngAnimate module, and a directive that uses ng-repeat with dynamic class and ng-show (and more, which did not seem to affect the problem). Removing any of those mentioned had solved the issue.
there is one thing I didn't try and that's trying to detach the code from the ui-view hierarchy, perhaps the ui-router is a part of the problem.
Debugging showed that after the ng-class/ng-show's watch executes, the right class was added and it looked like this: class="{{::item.customClass}} ng-hide", but at the end of the digest cycle it looked like this: class="myCustomClass". I guess that is what happens in your code as well.
The way I handled this situation is by moving item.customClass to the ng-class like so: ng-class=[{ ... other classes}, item.customClass]
it's a workaround and not a real solution because:
it's probably a real issue inside Angular's code.
I don't know how to use bind once here, and it's important of course.
Take a look at animate.css. It works with Angular and you can trigger it by class='ng-show'.
Like this:
<div class="animated fadeInRight" data-ng-class="loginShow">
If you set $scope.loginShow to 'ng-show' in your controller it will trigger the animate effect automatically.
If you want to trigger the animate effect on 'ng-hide' you have to write it in your controller like this:
$scope.loginShow = 'ng-hide-add animated fadeOutRight';
Hope this helps!

animations on ng-repeat within ui-bootstrap modal

I believe I have found a bug with ui-bootstrap, I reported an issue here:
https://github.com/angular-ui/bootstrap/issues/4222
Would anyone have any tips on how to write a workaround for this in the meantime until it gets solved?
Basically, angular's animation hooks are not applied to elements within a ui-bootstrap modal, the plunker is posted in the link above
Any help much appreciated

Problems with a reusable Click to Edit Directive on AngularJS

I'm using the Reusable Click to Edit Directive from Icelab. I've used it successfully in several places in my app, but I run into problems when I try to edit elements that are inside other directives.
As the directives are calling the elements one by one, as in the following code:
<my-continent text='{{questions.n2A.answer.1.name}}' continent-id="1"></my-continent>
I don't see how can I implement the reusable directive in them, as it generates a general block of html code, not a specific one for each element called with the directive my continent.
I've created a Plunker where the problem is visible.
If I add the click-to-edit directive into my-continent, it breakes. You can see what I mean on line 47 of the html, when I add click-to-edit="questions.n2A.answer.1.name" onto the line as shown under.
<my-continent text='{{questions.n2A.answer.1.name}}' continent-id="1" click-to-edit="questions.n2A.answer.1.name"></my-continent>
Any idea about what am I missing?
Thanks!
I've used your plunker to check your problem and the moment I added click-to-edit to myContinent I've got an error in console linking to this:
Error on AngularJS
So basicly your code is not working because you create new scope in both directives. Hope that helps

Categories