首页 > 解决方案 > 如何使 Angular 动画正常工作

问题描述

我正在使用 ngx-toastr(使用角度/动画)来显示敬酒。如果我从手动创建的事件中触发它们,那么我的动画会有很大的延迟。

  export class AppComponent {
      @ViewChild('iframeElement') iframeElement: ElementRef;
      html = `<!DOCTYPE html><html lang="en"><head><title></title></head><body><div>2. Step 2</div><ul><li>Wait when toast is gone</li><li>Click here 3 times quickly</li><li>Wait few seconds to see toasts</li></ul></body></html>`;

      constructor(private toastr: ToastrService,
                  private renderer: Renderer2) {
      }

      load(e) {
        console.log('Iframe Loaded');
        const iframe = this.iframeElement.nativeElement;

        this.renderer.listen(iframe.contentDocument, 'click', (e) => {
          e.preventDefault();
          console.log('Iframe body clicked', e, e.target);
          this.showMessage('Message From Iframe');
        });
      }

      showMessage(message: string) {
        this.toastr.success(message);
      }
  }

和模板:

<button type="button" (click)="showMessage('Just a message')">1. Press Me</button>

<div>
  <iframe #iframeElement src="about:blank" (load)="load($event)" [srcdoc]="html" frameborder="1"></iframe>
</div>

我可以看到 toast 会立即添加到 DOM,但它们会在添加到 DOM 后几秒钟内显示出来。

这是演示

标签: angularangular-animationsngx-toastr

解决方案


来自 iframe 的事件在 Angular 区域之外处理。你应该在里面处理它们:

import { NgZone } from '@angular/core';

constructor(...private ngZone: NgZone) {}

load(e) {
  ...

  this.renderer.listen(iframe.contentDocument, 'click', (e) => {
    ...
    this.ngZone.run(() => this.showMessage('Message From Iframe'));
    ^^^^^^^^^^^^^^^^^^
  });
}

分叉的 Stackblitz


推荐阅读