How to apply an animation on an item that is getting removed without using a timeout - angularjs

I'm using Angular 2 - RC3.
My problem is, I have an item which is shown or hidden using a *ngIf.
When the item is getting shown or hidden I want to apply an animation.
I'am able to apply an animation when the item first shows simply by adding a class. But the problem is when it's getting removed, the item gets removed from the screen before the animation can start/finish.
I know you can overcome this by setting a timer to delay removing action so that the animation can finish. But I don't want to put timers everywhere I need this functionality.
Is there an easier way in Angular to achieve this?
I don't want to use JQuery is either.

Use [hidden] directive on your element, as it does not prevent the element from rendering like *ngIf does.
[hidden] mean it takes up space in your DOM document but it's display is set to : none !important.
*ngIf on the other hand removes the element from the DOM completly

Related

Using collapsible panels within react-virtualized List

I've managed to render a react-virtulized List to which I passed an array of react-bootstrap Panels. I've measured each of my rows, and via children callback, each time one of the child panels are clicked, an attribute in the parent state is updated. Said attribute is used inside the react-virtualized List rowHeight() function top check whether that panel is currently expanded. Then, using a ref to my List, i call the recomputeRowHeights(index) and forceUpdateGrid() methods on saidref.
The thing is, while the List component correctly updates both the height and position of my rows, the animation isn't smooth. I mean, the bootstrap expand animation works fine, but the change in height of the expanded row happens instantly after the click event, and then the animation starts, feeling somewhat chopy.
Is there any workaround for this, or is this an upcoming/planned/in the works feature for react-virtualized?
Unfortunately, I have not spent much time working with or optimizing for resize animations within react-virtualized. It doesn't surprise me to hear that the resize/reposition is a bit choppy in the case you mention.
Here's a quick-and-dirty example of one way you may add animation: plnkr.co/edit/VanCAQmSkUejp3hbJUyJ?p=preview. Not meant to be bug free, just an illustration. :D

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.

AngularJS ng-class Expression Not Updating Properly

So I'm trying to build a custom autocomplete dropdown for a text input. To do it, I am listening for the keydown event and if it's an up or down arrow press, I'm setting a $scope.arrowSelectedItem variable to the proper one in the list. (As a side note, all the functionality works as far as selecting an item from the list that pops up. All I'm trying to do is highlight the current one that they've marked with the up/down arrows).
On the markup side, the items in the autocomplete list are output with ng-repeat, with ng-repeat="item in itemList". The ng-class expression I'm using is ng-class="{highlighted: item === arrowSelectedItem}". I know that the $scope.arrowSelectedItem is being updated on each arrow press by using console.log, but for some reason the class isn't being updated to the list item properly.
What I've found is that after the first time of hitting an arrow key, if I make the text input box lose focus, then the class is added. Then if I click back in the box, move the arrow to select a different item, click out of the input box, then click back in, the class is added to the new one. I know that sounds weird, but that's what I've found.
What I'm not sure about is why the ng-class expression isn't being evaluated on every arrow key press. Does anyone have any ideas why?
The answer here is that "raw" DOM events which fire outside of one of angular's built in directives (such as click events via ng-click etc) will not trigger a $digest cycle update. Until this happens the $scope properties will not be updated.
If you are in a position where you are listening for DOM events by using another framework, or simply using addEventListener(), you will need to let angular know about any changes by using $scope.$apply(), or by wrapping the code in a $timeout().
If you do this in your event handler, angular will trigger a new $digest cycle update for every keypress and your new scope values will propagate to the view.

Dojo drop-down detaches when scrolling page containing FilteringSelect or ComboBox

Since the ComboBox and FilteringSelect use a 'dijitPopup' whose DOM element gets inserted just before the closing body tag (presumably to help with ensuring it appears above everything else z-index-wise) this means that if the ComboBox is contained in an element that scrolls independent of the window itself and the user opens the dropdown and then scrolls the window (or whatever containing element) using the scroll wheel, that the menu part doesn't move with the control itself.
Is there a straightforward way to ensure that the menu part of the view remains positioned correctly relative to the control itself rather than simply assuming that its starting position is ok?
EDIT: appears to be a known issue (http://bugs.dojotoolkit.org/ticket/5777). I understand why they put the dijit popup just before the closing body tag for z-index stacking and overflow clipping issues, but it seems like it's maybe not the ideal way to do things given the bug in question here and things like:
You can restrict the Dijit theme to only small portions of a page; you
do this by applying the CSS class of the theme to a block-level
element, such as a div. However, keep in mind that any popup-based
widget (or widgets that use popups, such as dijit.form.ComboButton,
dijit.form.DropDownButton, and dijit.form.Select) create and place the
DOM structure for the popup as a direct child of the body
element—which means that your theme will not be applied to the popup.
~ from http://dojotoolkit.org/documentation/tutorials/1.6/themes_buttons_textboxes/
Not sure if this is the very best solution, but here's what I came up with:
Since the widget may be programmatically added/removed, and to avoid coupling a solution with some particular surrounding markup that we can't always count on in all cases, what I did was to hook the _showResultList and _hideResultList methods of ComboBox and when the popup opens, traverse up the DOM till we reach the <html> tag, adding onscroll listeners on each ancestor.
The handler for the onscroll event is simply:
var myPos = dojo.position(this.domNode, true);
this._popupWidget.domNode.parentNode.style.top = '' + (myPos.y + myPos.h) + "px";
where this is the widget in question. I scope the handler to the widget using dojo.hitch. In the close method I remove the listeners. I have to clean up the code a bit before it's presentable, but when it's finalized I'll add it to this answer.
Note: I only show updating the y position here. Part of the cleanup is to add x position updating in case someone scrolls horizontally.
Though its old I just faced this same problem and it looks like a Dojo issue and the fix is available here https://bugs.dojotoolkit.org/changeset/30911/legacy

Resources