Sometimes view not updated completely - angularjs

Parts of a view of my Angular app are not rendered correctly - sometimes.
The behaviour is very strange, because this happens only sometimes and for certain items only.
My app consists of a service, a controller and a view. The service communicates with a backend and provides data for the controller. The controller is watching for certain data. With data-binding the values are shown in the view.
In general the shown values are correctly - I can see it in the logs. But sometimes when the a value has changed, not all depended view elements get updated - but some of them.
I mean a DIV shows the text of a certain value with ng-bind.
Moreover another DIV is visible or hidden with ng-if and depends on the same value of the same controller.
Sometimes I have the behaviour that the visibility of the button is switch correctly but the text of the other DIV does not (shows the old text).
It switches only if I scroll the view (or touch it on mobile device). Is this the next digest cycle maybe?
Otherwhile everything is rendered complete correctly!
I have already tried it with a directive and without one, with the 'controllerAs' syntax and without, with Angular 1.2 and 1.3 - but everytime the same result.
Has anyone further ideas to this behaviour?
Can this be a rendering problem?

Related

Is there an event that is sure to fire when google maps is loaded, when using angular js?

I am using angularjs and ngmap (https://ngmap.github.io).
The map is initially hidden from view (using ng-show), and i want to be able to toggle between views without having to reload the whole map.
I also want to display a kml on the map.
The map is only initialized (using lazy initialization) when that part of the page is shown.
It seems to work fine, except that sometimes the map can't zoom into the kml (using fitBounds). I think I have established that this is because the height of the containing div is zero (due to the controller code firing before the view is actually rendered), and fitBounds needs that.
I am trying to wait until I am sure the map is good and ready. I have tried the following events:
bounds_changed
tilesloaded
but neither do what I want.
Currently I am using a $timeout, but I don't like it, as I don't know how long it takes to initialize the map, and whether or not my code will fire between that time.
My next idea is to repeatedly check for the height of the map, but I would prefer something more explicit.
Another idea is to always have the map in the background, and use absolute positioning to cover it with the other information when that part is visible, but that breaks my current design.
I've decided to avoid the issue.
The map is always going to be there, but I use some ng-class s to make it "visibility: hidden" and hide an unneeded scroll bar when the map tab is unselected.
As long as the visibility is hidden (instead of display: none) the initialization and positioning of the map goes okay.
It isn't perfect (I might need to scroll the other tabs one day), but it works for me for now.

AngularJS - DOM-Elements are flickering

lately I have a pretty significant problem with ng-view and ng-if.Suppose there is a dropdown with two elements (element one and element two).The two elements change a property on rootScope.
I have two more items at another location (div-container, container one and two containers). These are displayed by ng-show - container one at element one and container at element two.
As soon as I click the one element one time and the property of the rootScope changes and then I reload the page, the two containers are alternately displayed without that I do something.
I have several watchers, seveleral ng-cloaks and use the routing using ng-view. I would also like to mention that the application is relatively large. Most often, the problem occurs on Android, presumably on iOS.
As soon as I click the one element one time and the property of the
rootScope changes and then I reload the page, the two containers are
alternately displayed without that I do something.
Did you mean the other two containers just show up for a second and then disappear? If that is the case then I think the condition you are providing inside ng-show is true at the loading time so they appear for a while before the condition changes and then they disappear.
You have to make sure the condition for ng-show is initially false.

It takes 2 clicks for change in angular directive

Ok, so I'll just start off saying I'm almost certain this bug is either arising from my lack of understanding of isolate scoping in angular directives or some weird interaction between directives and the angular google maps markers directive.
Anyways, the issue is that I have an instance of the angular-google-maps stuff in my main controller, and I have a tag within that. I also have a directive which is captures user inputs and uses them to populate a list in the main controller for the tag to do its thing. I pass in an object and function from the main controller into the directive's isolate scope.
The weird thing is that within my directives, I have bound this function onto a button click for a form, and for some reason, it takes 2 clicks to get the marker to appear. The function fires the first click, it has all the right values and everything, but the marker doesn't appear. Another weird I checked was simply calling the method twice in a row for one click which didn't work (still required 2 button presses).
The function modifies the array in the main controller (I have a feeling this is the root of the issue) which is used by the tag as a list of markers. Any ideas on why this could be happening? If it doesn't seem like an obvious misunderstanding of Angular scoping, I can post code.
My first thought is your data is happening outside of the digest loop. And if that's the case then adding a $scope.$digest() after your data is updated might solve it (or give you a console error).

angular-strap tooltip not working in ng-repeat

Question: Is there a bug in angular-strap? Or do I misunderstand how Angular works, and this is expected?
I've created a plunker to demonstrate the behavior.
What I want:
I want to show a different tooltip for each item in an ng-repeat.
Behavior I'm seeing:
Under certain conditions, the tooltip content is not properly inserted into the content template. Thus you only see the template, and not the content template or content itself.
Conditions:
When the page is first loaded, the tooltips work as expected.
When an item is added to the ng-repeat, its tooltip does not populate the template's content section.
If the page starts off with zero items in the ng-repeat, the tooltip in the first item added will work as expected. Items added after that will exhibit the problem.
Regardless of how many items the ng-repeat starts with, any removal of any item from it will make all items added in the future not have working tooltips.
Thoughts: If I boil it down, the "first load" works fine. After that, it doesn't. I'd guess that what happens is that there's a compilation step happening after the first round of adding items into ng-repeat. At that point, the angular-strap tooltip code sees the directive attributes, and sets up those tooltips and the content template. Subsequent changes to the ng-repeat are missed by angular-strap (even though I can see in the console that the call from bs-popover=tooltip(item) does actually run each time the ng-repeat list is updated). But I'm still stumped and wondering if this is behavior I can get around.
How do I allow dynamic tooltips in items added to an ng-repeat?
This seems to work in _popover.html
<div class="popover-content">{{content}}</div>
That is using {{ }} instead of ng-bind...works very odd.
Upon further investigation... Its probably happening somewhere around here:
https://github.com/mgcrea/angular-strap/blob/master/src/tooltip/tooltip.js#L83
Though I don't know where/how/what yet.
Update
So the bug (in Angular-Strap) is with caching your template. Initial retrieval (via http) works fine. But it caches them as an array, and upon retrieval from cache (subsequent additions) it gets an array. Which doesn't have a .data property so your template is empty, and your ng-bind is removed..

how to prevent AngularJs from having old view and new view on dom when route changes

I am using a directive "slideable" which creates a slideout area and has a toggle. This code that was not written by me but it demonstrates a larger issue for me. When I changing views (most commonly /user/:id type), slideable is a directive used on the template. The directive searches for an element during its link function and binds a click event. The issue is that when I am changing routes and the new view ( same type but different id ) is being loaded the directive is re-binding to the old view. If I stop the browser in chrome during the link then I will see two ng-views on the dom and the issue is it binds to the one that is leaving.
I also have other issues that appear to be related to this phenomenon. Is it normal that the old view would still be on the dom while the new view is being formulated?? Why wouldnt the old-view be destroyed before the new one is rendered? How do I get around this issue in a directive like this?
Thanks.
I am looking to understand conceptually what is happening. I already modified the directive to select the latest view and to appropriately search and bind to the correct element. But I am a bit perplexed as to why there would be a state where both co-exist on the dom.
One definitive reason why the old HTML fragment is briefly present along with the new one is to support animation of transitions from the old to the new. Take a look at the ngView documentation and you'll see an example of an animated transition, and it'll be clear that this is not a bug or a design flaw.
Usually when someone has problems with binding to the right element or element's event, it's because they are selecting the element without limiting the scope of the selector to the HTML fragment being added or updated, or trying to target parts of the DOM outside of the directive. So that's the first place to check, that the directive is doing things right, but like I said we'll need code to check on that.

Resources