Angular 离子型/角型+;洛蒂:分别为每个洛蒂制作动画?

Angular 离子型/角型+;洛蒂:分别为每个洛蒂制作动画?,angular,ionic-framework,lottie,Angular,Ionic Framework,Lottie,在我继续之前,我应该注意到我之前发布了一个类似的问题,内容与此类似,但我认为错误的来源是使用ngFor循环中的自定义组件。我发现这不是问题所在,所以我删除了原来的问题,以使我的问题更加准确,并且不会误导任何人 我目前正在做一个使用Ionic 5和Angular 9的项目,我们必须在某些视图中使用乐透。我使用的是ngx lottie库(),出于我的目的,我没有像库的API那样在每个视图的模板中插入lottie,而是构建了一个包含在其他视图中的组件。所述部件的代码如下: import { Compo

在我继续之前,我应该注意到我之前发布了一个类似的问题,内容与此类似,但我认为错误的来源是使用ngFor循环中的自定义组件。我发现这不是问题所在,所以我删除了原来的问题,以使我的问题更加准确,并且不会误导任何人

我目前正在做一个使用Ionic 5和Angular 9的项目,我们必须在某些视图中使用乐透。我使用的是ngx lottie库(),出于我的目的,我没有像库的API那样在每个视图的模板中插入lottie,而是构建了一个包含在其他视图中的组件。所述部件的代码如下:

import { Component, OnInit, OnChanges, SimpleChanges, Input } from '@angular/core';
import { AnimationItem } from 'lottie-web';
import { AnimationOptions } from 'ngx-lottie';

@Component({
  selector: 'app-lottie-player',
  template: `<ng-lottie
  [options]="options"
  [styles]="styles"
  (animationCreated)="animationCreated($event)">
  </ng-lottie>`,
})

export class LottiePlayerComponent implements OnInit, OnChanges {

  @Input() lottieToPlay: string;        // Route to the json within assets/lotties
  @Input() lottieToUpdate: string;      // Secondary json in case a switch is needed
  @Input() animationDirection: number;  // 1 for normal direction, -1 for reversed animation
  @Input() dimensions: any;             // Layout specifications passed from parent component

  options: AnimationOptions = {
    path: '',
  };

  styles: Partial<CSSStyleDeclaration> = {
    margin: '0 auto',
  };

  private animationItem: AnimationItem;

  constructor() { }

  ngOnInit() {
    this.updateAnimation();
  }

  ngOnChanges(changes: SimpleChanges) {
    const directionChange = changes.animationDirection;
    if (directionChange && !directionChange.firstChange) {
      this.playAnimation(this.animationItem, directionChange.currentValue);
    }
  }

  updateAnimation(): void {
    this.options = {
      ...this.options,
      path: this.lottieToPlay,
    };
    this.styles = {
      ...this.styles,
      ...this.dimensions
    };
  }

  animationCreated(animationItem: AnimationItem): void {
    this.animationItem = animationItem;
    this.animationItem.autoplay = false;
    this.animationItem.loop = false;
  }

  playAnimation(animationItem: AnimationItem, direction?: number): void {
    this.animationItem = animationItem;
    this.animationItem.setDirection(Math.sign(direction) === 1 ? 1 : -1);
    this.animationItem.play();
  }

}
乐透按计划进行。动画仅触发一次,并保持在其完成动画状态

当我像上面那样插入lottie时,问题就出现了,但是在同一个组件中插入了几个,而不是一个。我现在相信,问题的原因可能是我构建了错误的原始组件。在另一个组件中,我插入了乐透播放器,如下所示:

    <ion-buttons slot="secondary">
      <ion-button class="icon-container" (click)="changeIconAndNavigate()">
        <app-lottie-player
          [dimensions]="lottieClassSpecs"
          [lottieToPlay]="lottieFav"
          [animationDirection]="lottieAnimDirection">
        </app-lottie-player>
      </ion-button>
    </ion-buttons>
<ion-item *ngFor="let card of cards" class="card-info">
...
          <ion-item lines="full">
            <span class="card-span">{{ card.title }}</span>
            <ion-button class="lottie-holder" (click)="toggleSingleSubscription(card)">
              <app-lottie-player
              [dimensions]="lottieClassSpecs"
              [lottieToPlay]="lottieAdd"
              [animationDirection]="lottieAnimDirection">
              </app-lottie-player>
            </ion-button>
          </ion-item>
...
</ion-item>

...
{{card.title}

上面的乐透也有动画

不仅是上面卡中的一个,而且出于测试目的,
我尝试在ngFor循环上方插入动画。我认为这个错误的原因可能是,因为我是如何构建这个基本组件的,而不是在控制器中创建播放器的一个实例,它正在重新更新同一个实例,使接收到的信息显示在DOM中的所有插入中,因为它们实际上都来自一个实例。但我不知道如何解决它


如果有人对彩票中的这个错误可能发生的原因有一点想法,我会全神贯注。

我制作了一个stackblitz,显示我认为您的问题是,所有组件都被传递到同一个状态实例

div
s的第一个数组在父级中都有一个状态,因此将其切换为一个会更新所有的状态

第二个
app card
s都是它们自己的组件,它们都有自己的状态。请注意,由于我们仍然将全局状态作为输入传入,而在内部更改它时,它不会更新其他状态,但如果在父级更新它,则会将该新值下推到所有子级

子组件示例

从'@angular/core'导入{Component,OnInit,Input};
@组成部分({
选择器:“应用程序卡”,
templateUrl:“./card.component.html”,
样式URL:['./card.component.css']
})
导出类CardComponent实现OnInit{
@Input()卡:{id:number,title:string};
内部状态=真;
@Input()stateFromParent:boolean;
构造函数(){}
恩戈尼尼特(){
}
toggleInternalState(){
this.internalState=!this.internalState;
this.stateFromParent=!this.stateFromParent;
}
}
子组件模板


ID:{{card.ID}

标题:{{card.Title}

internalState:{{internalState | json}}

stateFromParent:{{stateFromParent | json}}(注意:它将管理自己的内部值,但如果父级的输入发生更改,则将传入新值)

切换值
切换SingleSubscription(卡)
的代码是什么样子的?您还应该显示您的父代码。在我听来,根据你的for循环,你给每一张卡传递相同的乐透输入。您可能需要制作一个卡组件,每个卡组件都可以管理自己的lottie输入及其状态。@cjd82187
toggleSingleSubscription()
检查卡的id是否在阵列中,如果不在,则插入,如果不在,则弹出,然后更新此。lottieAnimDirection。起初,我怀疑你所建议的(ngLoop本质上给每个人相同的乐透输入)是原因。但是对于ngFor之外的乐蒂来说,动画制作也没有意义是的,因为循环没有自己的范围。这只有一个
。lottieANimDirection
在父组件中,它将该值传递给其模板中的所有内容我添加了一个答案,并用stackblitz说明了我正在谈论的问题。这样的事情有时会让我质疑我作为一名角度开发人员的能力。。。如果这不是我第一次使用ngFor或ngIf等条件创建“随需应变”卡,这种疏忽本来是正常的。总之,你搞定了——我没有使用ngFor在父模板中生成卡片,而是为它们构建了一个子组件,这样每个组件都有自己的状态和
app-lottie-player
insertions,瞧。现在你可以独立活动了
<ion-item *ngFor="let card of cards" class="card-info">
...
          <ion-item lines="full">
            <span class="card-span">{{ card.title }}</span>
            <ion-button class="lottie-holder" (click)="toggleSingleSubscription(card)">
              <app-lottie-player
              [dimensions]="lottieClassSpecs"
              [lottieToPlay]="lottieAdd"
              [animationDirection]="lottieAnimDirection">
              </app-lottie-player>
            </ion-button>
          </ion-item>
...
</ion-item>