0

我有一个 Angular 4 应用程序和一个组件,它们会动态生成一些标记。我需要将此组件的方法绑定到此标记中的某个元素。我发现的唯一方法是使用onclick属性生成此元素。所以现在我的组件的构造函数看起来像这样:

constructor(private _zone: NgZone) { 
    window['Component'] = {
      myMethod: this.myMethod.bind(this),
      zone: _zone
    }
}

...我生成的标记看起来像这样:

<button onclick="window.Component.myMethod()">I was generated dynamically after Angular compilation, so you can't use '(click)="method(params)"' on me! Haha!</button>

它有效!几乎...单击按钮后,我需要window触发一些事件(例如焦点或模糊),然后我的方法才会运行。请任何人帮忙。

4

2 回答 2

0

看起来问题是当我在 Angular 区域之外运行该方法时,UI 不会刷新。所以我这样做了:

(<any>window).myMethod = (params) => this._zone.run(
    () => {
        this.myMethod(params);
    });

不知道这个解决方案有多好,但它工作正常。

UPD:哎呀,不好。该方法在我第一次单击按钮时没有运行,之后一切正常。

于 2018-03-26T09:32:16.523 回答
0

你必须使用:this.zone.runOutsideAngular

我附上了示例来说明您在组件内部有角度和事件绑定的按钮。如我的示例所示,不要忘记取消绑定您的事件 onDestroy。

this.zone.runOutsideAngular(() => {
  document.querySelector('#btn').addEventListener('click', () => {
    this.foo();
  });      
});

https://stackblitz.com/edit/angular-xtkw3z?file=app%2Fapp.component.ts


更新1:

我创建了专门用于绑定按钮上的单击事件的自定义指令。

我删除了 DOMSanitizer,因为我们自动添加了 Event.stopPropagation()。所以你必须自己控制字符串是否安全。

@Directive({
  selector: '[profil]'
})
export class UserProfilDirective implements OnInit, AfterViewInit {
    @Input('profil') html: string;

    constructor(
        private el: ElementRef,
        private zone: NgZone,
        private renderer: Renderer2
    ) {
    }
    ngOnInit() {
        //Take your html and add it as child html if current directive instance.
        this.el.nativeElement.innerHTML = this.html;
    }
    ngAfterViewInit() {
        //Out of angular.
        this.zone.runOutsideAngular(() => {
            // For each .profil of current instance.
            [].forEach.call(this.el.nativeElement.querySelectorAll('.profil'), (el:Element, index: number) => {
                //Ask rendering to add onClick event.
                this.renderer.listen(el, 'click', (e) => {
                  //Do what ever you want with data profil such as output Event
                  console.log(e.srcElement.getAttribute('data-profile'));
                });
            });
        });
    }
}

源代码在这里: https ://stackblitz.com/edit/angular-cua3is?file=app/app.component.ts

于 2018-03-26T10:02:03.193 回答