0

I basically route from a parent component(album component) which goes to the musicList Component. The musicList component gets the music data stored in the activated router which simply resolves it from a resolver service (although I have tried calling it directly but still same animation issue).

The template using an *ngIf adds and removes each music data upon each call to various id on the router but only animates on loading the page or refreshing it. Why is it acting this way?

<h2>My Album</h2>
<ul class="crisisAlbum">
  <li *ngFor= "let crisisMusic of crisisAlbum" [class.selected]="crisisMusic === selectedCrisisMusic" (click)="onSelect(crisisMusic)"><a [routerLink]="['/crisis-center', crisisMusic.id]">
    <span class="badge">{{crisisMusic.id}}</span>{{crisisMusic.music}}</a>
  </li>
</ul>
<router-outlet ></router-outlet>
<app-message></app-message>

which takes me to child component (music List component) <Template>

<div class="g" @slide *ngIf="crisisMusic" >
  <div >
  <h2> {{crisisMusic.music | uppercase}} Details</h2>
  <div><span>id: </span>{{crisisMusic.id}}</div>
  <div >
    <label>name:
      <input [(ngModel)]="crisisMusic.music" #crisisSong placeholder="name" />
    </label>
  </div>
  <button (click)="save(crisisSong)">Save</button>
  <button (click)="back()">Back</button>
</div>
</div>

<Component>

import { Component, OnInit, Input } from '@angular/core';
import { Observable } from 'rxjs'
// import {music} from '../musicInterface'
// import { MusicService } from '../music.service';
import { crisis } from '../crisis'
import { ActivatedRoute, Router, Params } from '@angular/router';
import { switchMap, timeout, map } from 'rxjs/operators';
import { CrisisService } from '../crisis.service';
import { DialogService } from 'src/app/dialog.service';
import { trigger, query, state, style, transition, animate, stagger } from '@angular/animations';

@Component({
  selector: 'app-music-list',
  templateUrl: './music-list.component.html',
  styleUrls: ['./music-list.component.css'],
  animations: [
    trigger('slide', [
      transition(':enter', [
        style({transform: 'translateX(100%)', opacity: 0, zIndex:100}),
        animate('500ms')
      ]),
      transition(':leave', [
        style({transform: '*', opacity: '*', zIndex:100}),
        animate('1000ms',style({transform:'translateX(100%)',zIndex:200, opacity:0}))
      ])
    ]
    )]
})
export class crisisMusicListComponent implements OnInit {
  @Input() animat: boolean;
  show:boolean= false;
  // @Input() crisisMusic:crisis
  public crisisMusic: crisis;
  private crisisId: number;
  public crisisSong

  constructor(private crisisMusicService: CrisisService, public dialogService: DialogService, private route: ActivatedRoute, private router: Router) {

  }
  isShow(){
    console.log('yes')
    this.show= !this.show
  }


  ngOnInit() {
    this.route.data
      .subscribe((data: { crisis: crisis }) => {
        this.crisisId = data.crisis.id
        this.crisisMusic = data.crisis;
        this.crisisSong= data.crisis.music
        console.log(data.crisis)
      });

  }
  back() {
    this.router.navigate(['../', { id: this.crisisId, foo: 'foo' }], { relativeTo: this.route })
  }
  save() {

    this.crisisSong = this.crisisMusic.music;
    console.log(this.crisisSong)
    this.router.navigate(['../', { id: this.crisisId, foo: 'foo' }])
  }
  canDeactivate(): Observable<boolean> | boolean {
    // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
    if (!this.crisisMusic || this.crisisMusic.music === this.crisisSong) {
      return true;


    }
    // Otherwise ask the user with the dialog service and return its
    // observable which resolves to true or false when the user decides
    this.dialogService.confirm('Discard changes?').subscribe(d=>{
      if(d){
        this.save();
        // this.router.navigate(['/crisis-center',this.route.snapshot.paramMap.get('id')])
      }
    });
  }

}

Note the data is gotten from a resolver service.

I was hoping for the element to animate on removing and adding a new album each time the *ngIf is triggered.

halfer
  • 19,824
  • 17
  • 99
  • 186
Charles
  • 3
  • 1

2 Answers2

0

Put the animation on routing:

<router-outlet @slide></router-outlet>
Chris
  • 2,117
  • 13
  • 18
0

This transition will happen on enter or leave. That means in that case, when the condition in the ngIf changes. Since it can only evaluate to true or false, it can only change if crisisMusic changes from undefined to something defined or vice versa. By default, it is undefined, and when the first set of data arrives through the route, it will be defined. That is where the animation happens the only time. So you would need to bind your ngIf or your animation to some different condition which really checks if this element has just been added or removed.

seawave_23
  • 1,169
  • 2
  • 12
  • 23
  • I figured it updates much faster, so i had to reset crisisMusic to undefined everytime i subscribe to the router and add a timeout on getting the data from the router,so both entering and leaving animation works. `this.route.data .subscribe((data: { crisis: crisis }) => { this.crisisMusic= undefined setTimeout(()=>{this.crisisMusic=data.crisis}, 1000) });` it works, now i don't know if network latency will make it work without the timer or i should probably leave the timer. I guess i might have to figure that out. Thanks mate – Charles Apr 07 '20 at 07:59