简体   繁体   中英

Angular 2 animation with async data

I have the following component which will simply fetch a dataset of skills containing a title and a percentage from my database.

My goal is to have the initial width value on each div be 0% and once the http request has come back and the correct information is retreived, set the correct percentage for each skill with an animation that goes from left to right (the divs will have a background-color so you should see its width grow, ex.: 0% ---> 95%).

I'm wondering what would be the best approach to accomplish this in a correct Angular 2 treatment. I know there's an animation property you can use on the component decorator but I'm not sure as to how to make it work with the async results coming in.

The most important thing about this question is how to handle the data that comes in through the async pipe in a way that I can show an animation for the percentage bump. Form 0 to whatever it will be. As it is now I immediately see the final result, however, an animation is never executed (and the anim is what I'm actually looking for, not just printing the final bar result).

I'm sure there are a few different ways to get this working, just confused as to which would be the best.

Here's my component:

import { Component, OnInit } from '@angular/core'
import { SkillsService } from './skills.service'

@Component({
  selector: 'skills',
  template: `
    <section class="skills">
      <div *ngFor="let skill of skillsService.skills$ | async">
        <div class="skills__bar" [style.width]="skill.percentage + '%'">
          <h3 class="skills__title">{{skill.title}}</h3>
        </div>
      </div>
    </section>
  `,
})
export class SkillsComponent implements OnInit {

  constructor(private skillsService: SkillsService) {}

  ngOnInit() {
    this.skillsService.fetchSkills()
  }
}

Thanks in advance, all!

You can use a CSS transition like so:

 //Demo purposes only. $("#get-skills-btn").on("click", function() { var randomValue = Math.random(); $(".skills__percentage").css("transform", "scaleX(" + randomValue + ")"); });
 .skills__bar { background-color: silver; text-align: center; position: relative; } .skills__percentage { background-color: green; position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform: scaleX(0); transform-origin: left; transition: transform 300ms cubic-bezier(0.175, 0.885, 0.32, 1.275); } .skills__title { position: relative; z-index: 1; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <section class="skills"> <div> <div class="skills__bar"> <div class="skills__percentage"></div> <h3 class="skills__title">{{skill.title}}</h3> </div> </div> </section> <button id="get-skills-btn"> Fetch Data </button>

For angular use something like this:

[style.transform]="scaleX(skill.percentage/100)"

With Angular 4.2+, we can do that using @angular/animations .

<div [@listParent]="len" class="list">
  <div *ngFor="let item of itemsAsync | async" [style.width]="item.val" class="item">
    {{item.name}}
  </div>
</div>

In component decorator, listParent animation is defined like:

animations: [
  trigger('listParent', [
    transition('* => *', [
      query(':enter', style({ width: 0 })),
      query(':enter', animate('1.6s', style({ width: '*'})))
    ])
  ])

listParent animation will be triggered whenever component property len changes.

In this plunker , try click Get one or Get multiple button.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM