Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

Angular 9 animation wont work with dynamic data

I'm trying to write a component that looks like on TV when sporting results will fly in row-by-row and build a result table. But now I have some Angular animations "side-effects".

My architecture looks like:

Scoreboard
    -- View results component
    -- View time keeping component
    -- View xyz component

The scoreboard is the major compontent that receives data via a Websocket service. Depending on the received data a view component is dynamically created (createComponent(...)) and shows the received data. That all works really well. Now I'm trying to add some nice animation effects, but this doesn't work as expected. All data are shown at once (without any animation), when the data is received from the Websocket service.

I tried to reduce it to a an example shown below:

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

@Component({
    selector: "my-app",
    templateUrl: "./app.component.html",
    animations: [
        trigger("listAnimation", [
        transition("* => *", [
            // each time the binding value changes
            query(
            ":leave",
            [stagger(100, [animate("0.5s", style({ opacity: 0 }))])],
            { optional: true }
            ),
            query(
            ":enter",
            [
                style({ opacity: 0 }),
                stagger(100, [animate("0.5s", style({ opacity: 1 }))])
            ],
            { optional: true }
            )
        ])
        ])
    ],
})
export class AppComponent {
    items = ["a", "b", "c"];

    ngOnInit() {}

    i = 0;

    ngAfterViewInit() {
        setInterval(() => {
        this.items = this.i++ % 2 == 0 ? ["1", "2", "3"] : ["x", "y", "z"];
        }, 3000);
    }
}

The component is created and shows an initial animation, but when the array is changed in setInterval() the view changes without any animation. Why does it behave as it does? Or better: where is my mistake and how to solve?

Please see https://stackblitz.com/edit/angular-list-animations-dndsja?file=app%2Fapp.component.ts for a working example.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Demo

There are multiple issues.

The first one is that you are trying to animate <tr> tags, I don't recommend to do this since the generated dom is different than the template.

So I switched to basic <div> tags to fix this.

The second is that your array is never empty, that's why there is no leave animation.

So I set its value to an empty array for an instant using the setTimeout function.

    setInterval(() => {
      this.items = [];
      setTimeout(() => {
        this.items = this.i++ % 2 == 0 ? ["1", "2", "3"] : ["x", "y", "z"];
      }, 0);
    }, 3000);

The third issue is that the animations are not synced, so I have to add a delay to the stagger animation in order to sync it.

I also did various tweaks to the animation to make it look good.

  animations: [
    trigger("listAnimation", [
      transition("* => *", [
        // each time the binding value changes
        group([
          query(
            ":leave",
            [stagger(100, [animate("0.5s", style({ opacity: 0 }))])],
            { optional: true }
          ),
          query(
            ":enter",
            [
              style({ opacity: 0, height: 0, visibility: 'hidden' }),
              stagger(100, [
                animate("0s 1.5s", style({})),
                style({ height: "*", visibility: 'visible' }),
                animate(".5s", style({ opacity: 1 }))
              ])
            ],
            { optional: true }
          )
        ])
      ])
    ])
  ],

NB: there are still errors throwing in the console that I have yet to figure out.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...