Angular 指令不应在导航后重新运行
Angular Directive should not rerun after navigation
我有一个指令应该为 div 内容设置动画。动画效果很好,但每次导航后都会重播。有没有办法只让它 运行 在初始页面加载时?
**编辑
我制作动画的元素在导航时重新呈现。
@Directive({
selector: '[appAnimateText]'
})
export class AnimateTextDirective implements AfterViewInit, OnInit {
@HostBinding('style.white-space') whiteSpace = 'pre';
private animateTo: string | undefined;
constructor(private el: ElementRef) {
}
get innerText(): string {
return this.el.nativeElement.innerText;
}
set innerText(newText: string) {
this.el.nativeElement.innerText = newText;
}
ngOnInit(): void {
this.animateTo = this.innerText;
// placeholder nbsp string which is than transformed back to the text
this.innerText = this.innerText.split('').map(() => ' ').join('');
}
ngAfterViewInit(): void {
if (this.animateTo) {
this.animate(this.animateTo.split(''));
}
}
animate(animateTo: string[]): Promise<void> {
// animation placeholder
return new Promise((res) => setTimeout(res, 2000))
}
我可以通过在我的服务中包含动画状态来解决问题。
我添加了一张带有 ngContentId 和布尔天气的地图,它是否完成。
// Service
export class AppService {
// ...
public appAnimationState = new Map<string, boolean>();
public getAnimationState(elementId: string): boolean | undefined {
return this.appAnimationState.get(elementId);
}
public setAnimationState(elementId: string, state: boolean): void {
this.appAnimationState.set(elementId, state);
}
// ...
}
// Directive
export class AnimateTextDirective implements OnInit {
@HostBinding('style.white-space') whiteSpace = 'pre';
private animateTo: string | undefined;
private ngContentId: string | undefined;
constructor(private el: ElementRef, private appService: AppService) {
}
get innerText(): string {
return this.el.nativeElement.innerText;
}
set innerText(newText: string) {
this.el.nativeElement.innerText = newText;
}
ngOnInit(): void {
this.ngContentId = this.el.nativeElement.attributes[0].name;
// I use the ngContentId assigned by angular, which does not change on
// navigation, that the animation only runs once
if (this.ngContentId && !this.appService.getAnimationState(this.ngContentId)) {
this.animateTo = this.innerText;
this.innerText = this.innerText.split('').map(() => ' ').join('');
this.animate(this.animateTo.split(''));
this.appService.setAnimationState(this.ngContentId, true);
}
}
animate(animateTo: string[]): Promise<void> {
// ...
}
}
我有一个指令应该为 div 内容设置动画。动画效果很好,但每次导航后都会重播。有没有办法只让它 运行 在初始页面加载时?
**编辑
我制作动画的元素在导航时重新呈现。
@Directive({
selector: '[appAnimateText]'
})
export class AnimateTextDirective implements AfterViewInit, OnInit {
@HostBinding('style.white-space') whiteSpace = 'pre';
private animateTo: string | undefined;
constructor(private el: ElementRef) {
}
get innerText(): string {
return this.el.nativeElement.innerText;
}
set innerText(newText: string) {
this.el.nativeElement.innerText = newText;
}
ngOnInit(): void {
this.animateTo = this.innerText;
// placeholder nbsp string which is than transformed back to the text
this.innerText = this.innerText.split('').map(() => ' ').join('');
}
ngAfterViewInit(): void {
if (this.animateTo) {
this.animate(this.animateTo.split(''));
}
}
animate(animateTo: string[]): Promise<void> {
// animation placeholder
return new Promise((res) => setTimeout(res, 2000))
}
我可以通过在我的服务中包含动画状态来解决问题。
我添加了一张带有 ngContentId 和布尔天气的地图,它是否完成。
// Service
export class AppService {
// ...
public appAnimationState = new Map<string, boolean>();
public getAnimationState(elementId: string): boolean | undefined {
return this.appAnimationState.get(elementId);
}
public setAnimationState(elementId: string, state: boolean): void {
this.appAnimationState.set(elementId, state);
}
// ...
}
// Directive
export class AnimateTextDirective implements OnInit {
@HostBinding('style.white-space') whiteSpace = 'pre';
private animateTo: string | undefined;
private ngContentId: string | undefined;
constructor(private el: ElementRef, private appService: AppService) {
}
get innerText(): string {
return this.el.nativeElement.innerText;
}
set innerText(newText: string) {
this.el.nativeElement.innerText = newText;
}
ngOnInit(): void {
this.ngContentId = this.el.nativeElement.attributes[0].name;
// I use the ngContentId assigned by angular, which does not change on
// navigation, that the animation only runs once
if (this.ngContentId && !this.appService.getAnimationState(this.ngContentId)) {
this.animateTo = this.innerText;
this.innerText = this.innerText.split('').map(() => ' ').join('');
this.animate(this.animateTo.split(''));
this.appService.setAnimationState(this.ngContentId, true);
}
}
animate(animateTo: string[]): Promise<void> {
// ...
}
}