【发布时间】:2020-07-24 13:18:07
【问题描述】:
在我继续之前,我应该注意我之前发布了一个类似的问题,内容与此类似,但是我认为错误的来源是在ngFor 循环。我发现这不是问题,所以我删除了原来的问题,以使我的查询更加准确并且不误导任何人。
我目前正在使用 Ionic 5 和 Angular 9 开发一个项目,我们必须在某些视图中使用 lotties。我正在使用 ngx-lottie 库 (https://github.com/ngx-lottie/ngx-lottie#api),出于我的目的,我没有像库的 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();
}
}
该组件主要执行以下操作:
- 从插入的任何父组件接收要呈现的 json。
- 从所述父级接收自定义 css 属性和抽奖的方向。
- 在“暂停”状态下启动抽奖,以触发点击动画。
所以当我将它插入到这样的视图中时:
<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>
在具有类似方法的父组件内部:
public changeIconAndNavigate() {
this.lottieAnimDirection = 1;
}
彩票按预期工作。动画只触发一次并停留在其完成的动画状态。
当我像上面那样插入 lottie 时出现问题,但是在同一个组件中进行了多次插入而不是单个插入。我现在相信问题的原因可能是我构建了错误的原始组件,可以这么说。在另一个组件中,我插入了这样的 lottie-player:
<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>
为了确定,我在 ngFor 循环之外插入了另一个 lottie-player 实例,看看它会如何反应。控制这些cards 的整个父组件只是简单地将它们插入或弹出到一个数组中,并且每次插入后,我根据需要将this.lottieANimDirection 更改为1 或-1,以便lottie 组件中的ngOnChanges可以拾取变化并相应地渲染动画
我期望看到的是每个乐蒂都单独制作动画 - 但他们都这样做了。因此,如果我单击底部的“订阅”...
上面的抽签也有动画。
不仅是上面卡片中的那个,还有用于测试目的的<app-lottie-player> 我尝试在 ngFor 循环上方插入也有动画效果。我相信这个错误的原因可能是,由于我是如何构建这个基本组件的,而不是在控制器中创建一个播放器实例,它正在重新更新同一个实例,导致接收到的信息将显示在 DOM 中的所有插入中,因为它们实际上都来自一个实例。但我不知道如何解决它。
如果有人对为什么会发生这个错误有一点点想法,我会全神贯注。
【问题讨论】:
-
toggleSingleSubscription(card)的代码是什么样的?您还应该显示您的父代码。根据您的 for 循环,在我看来,您正在向每张卡传递相同的 lottie 输入。您可能想要制作一个卡片组件,每个组件都可以管理自己的彩票输入及其状态。 -
@cjd82187
toggleSingleSubscription()检查卡片的 id 是否在数组中,如果不在则插入,如果不在则弹出,然后更新 this.lottieAnimDirection。起初,我怀疑您的建议(ngLoop 基本上向每个人提供相同的抽签输入)是原因。但是,在 ngFor 之外的 lottie 也进行动画处理是没有意义的 -
是的,因为循环没有自己的范围。您的父组件中只有一个
this. lottieANimDirection,并将该值传递给其模板中的所有内容 -
我添加了一个带有堆栈闪电战的答案,说明了我正在谈论的问题
标签: angular ionic-framework lottie