nativescript-angular icon indicating copy to clipboard operation
nativescript-angular copied to clipboard

*ngIf should wait for an animation to complete before removing a node

Open calebkiage opened this issue 8 years ago • 3 comments

I have the following animation defined

trigger('ngIfAnimation', [
    transition('* <=> *', [
        query(':enter', style({opacity: 0, transform: 'translateY(-200px)'}), {optional: true}),
        query(':leave', style({opacity: 1, transform: 'none'}), {optional: true}),
        group([
            query(':leave', animate(1000, style({opacity: 0, transform: 'translateY(-200px)'})), {optional: true}),
            query(':enter', animate(1000, style({opacity: 1, transform: 'none'})), {optional: true})
        ])
    ])
])

and the following structure in the template

<StackLayout class="sidedrawer-content" [@ngIfAnimation]="showLogin ? '1' : '2'">
  <StackLayout *ngIf="showLogin">
    <Label class="p-16" text="Login"></Label>
  </StackLayout>
  <ListView [items]="navigationItems" *ngIf="!showLogin" separatorColor="transparent">
    <ng-template let-item="item">
	<GridLayout columns="auto, *"
	            class="sidedrawer-list-item sidedrawer-list-item-{{item.name}}">
	    <Label row="0" col="0" [text]="item.icon" class="fa"></Label>
	    <Label row="0" col="1" [text]="item.title" textWrap="true"></Label>
	</GridLayout>
    </ng-template>
  </ListView>
</StackLayout>

When I run the app, the leave animation doesn't run because the node is immediately removed from the view. If a node is queried, it should stay in the view until the animation completes. This is how animation behaves in the browser.

package.json file

{
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": "<fill-your-repository-here>",
  "nativescript": {
    "id": "org.nativescript.testapp",
    "tns-android": {
      "version": "3.1.1"
    }
  },
  "scripts": {
    "lint": "tslint \"app/**/*.ts\"",
    "ns-bundle": "ns-bundle",
    "start-android-bundle": "npm run ns-bundle --android --run-app",
    "start-ios-bundle": "npm run ns-bundle --ios --run-app",
    "build-android-bundle": "npm run ns-bundle --android --build-app",
    "build-ios-bundle": "npm run ns-bundle --ios --build-app",
    "publish-ios-bundle": "npm run ns-bundle --ios --publish-app",
    "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install"
  },
  "dependencies": {
    "@angular/animations": "~4.2.6",
    "@angular/common": "~4.2.6",
    "@angular/compiler": "~4.2.6",
    "@angular/core": "~4.2.6",
    "@angular/forms": "~4.2.6",
    "@angular/http": "~4.2.6",
    "@angular/platform-browser": "~4.2.6",
    "@angular/router": "~4.2.6",
    "nativescript-angular": "~4.2.0",
    "nativescript-telerik-ui": "^3.0.0",
    "nativescript-theme-core": "~1.0.2",
    "reflect-metadata": "~0.1.8",
    "rxjs": "~5.4.0",
    "tns-core-modules": "~3.1.0",
    "zone.js": "~0.8.2"
  },
  "devDependencies": {
    "@angular/compiler-cli": "~4.2.6",
    "@ngtools/webpack": "~1.5.0",
    "babel-traverse": "6.26.0",
    "babel-types": "6.26.0",
    "babylon": "6.18.0",
    "codelyzer": "^3.0.1",
    "copy-webpack-plugin": "~4.0.1",
    "extract-text-webpack-plugin": "~3.0.0",
    "lazy": "1.0.11",
    "nativescript-css-loader": "~0.26.0",
    "nativescript-dev-sass": "^1.2.0",
    "nativescript-dev-typescript": "~0.5.0",
    "nativescript-dev-webpack": "^0.7.3",
    "node-sass": "*",
    "raw-loader": "~0.5.1",
    "resolve-url-loader": "~2.1.0",
    "tslint": "^5.4.3",
    "typescript": "~2.4.0",
    "webpack": "~3.2.0",
    "webpack-bundle-analyzer": "^2.8.2",
    "webpack-sources": "~1.0.1"
  }
}

calebkiage avatar Aug 21 '17 11:08 calebkiage

That would be extremely useful. Anything that removes something from the DOM should wait the animation completes or have an option for allow that.

andreferraz avatar Aug 31 '17 14:08 andreferraz

I know this issue is over 4 year old, but is there any workaround for getting a :leave animation working?

jzgoda avatar Apr 18 '22 12:04 jzgoda

Well, I found my own workaround using animation states without an ngIf involved:

import {
  trigger,
  transition,
  style,
  animate,
  state,
} from "@angular/animations";
import { Component } from "@angular/core";

@Component({
  selector: "ns-app",
  template: `<GridLayout rows="*, auto, auto" backgroundColor="#ffffff">
    <StackLayout row="0" rowSpan="3" verticalAlignment="center">
      <Button text="Tap Me" (tap)="show = !show" class="btn -primary"></Button>
    </StackLayout>
    <GridLayout
      row="1"
      class="notification"
      [@stateFade]="show ? 'show' : 'hide'"
    >
      <Label text="Hello!"></Label>
    </GridLayout>
  </GridLayout>`,
  styles: [
    "Button.-primary { font-size: 18; background-color: #0d2d6c; color: #ffffff; }",
    ".notification { color: #ffffff; font-size: 26; text-align: center; padding: 10; background-color: #0d2d6c; }",
  ],
  animations: [
    trigger("stateFade", [
      state("show", style({ opacity: 1, transform: "translateY(0)" })),
      state("hide", style({ opacity: 0, transform: "translateY(70)" })),
      transition("show => hide", [
        animate(
          "0.5s ease-in",
          style({ opacity: 0, transform: "translateY(70)" })
        ),
      ]),
      transition("hide => show", [
        animate(
          "0.5s ease-out",
          style({ opacity: 1, transform: "translateY(0)" })
        ),
      ]),
    ]),
  ],
})
export class AppComponent {
  show: boolean = false;
}

jzgoda avatar Apr 22 '22 15:04 jzgoda