Angular2 – 如何从应用程序外部调用组件函数

我正在使用一个有callback的JavaScript对象。 我希望一旦callback被触发来调用Angular2组件中的函数。

示例HTML文件。

var run = new Hello('callbackfunction'); function callbackfunction(){ // how to call the function **runThisFunctionFromOutside** } <script> System.config({ transpiler: 'typescript', typescriptOptions: { emitDecoratorMetadata: true }, packages: {'js/app': {defaultExtension: 'ts'}} }); System.import('js/app/main') .then(null, console.error.bind(console)); </script> 

我的App.component.ts

 import {Component NgZone} from 'angular2/core'; import {GameButtonsComponent} from './buttons/game-buttons.component'; @Component({ selector: 'my-app', template: ' blblb' }) export class AppComponent { constructor(private _ngZone: NgZone){} ngOnInit(){ calledFromOutside() { this._ngZone.run(() => { this.runThisFunctionFromOutside(); }); } } runThisFunctionFromOutside(){ console.log("run"); } 

我怎样才能调用函数runThisFunctionFromOutside是在App.component.ts内

另请参见如何公开angular2方法?

当构build组件时,将它自己分配给一个全局variables。 然后你可以从那里引用它并调用方法。 不要忘记使用zone.run(() => { ... })以便Angular获得有关所需更改检测运行的通知。

  function callbackfunction(){ // window['angularComponentRef'] might not yet be set here though window['angularComponent'].zone.run(() => { runThisFunctionFromOutside(); }); } constructor(private _ngZone: NgZone){ window['angularComponentRef'] = {component: this, zone: _ngZone}; } ngOnDestroy() { window.angularComponent = null; } 

Plunker example1

在浏览器控制台中,您必须从<topframe>切换到plunkerPreviewTarget....因为Plunker在iFrame执行代码。 然后运行

 window['angularComponentRef'].zone.run(() => {window['angularComponentRef'].component.callFromOutside('1');}) 

要么

 window.angularComponentRef.zone.run(() => {window.angularComponentRef.componentFn('2');}) 

另一种方法

将在Angular之外发送事件,并在Angular中倾听他们,就像在Angular 2中解释的那样- 使用外部js库

Plunker example2 (来自评论)

我基本上遵循这个答案 ,但是我不希望我的“外部”代码知道关于NgZone的任何事情。 这是app.component.ts:

 import {Component, NgZone, OnInit, OnDestroy} from '@angular/core'; @Component({ selector: 'my-app', templateUrl: 'app.component.html' }) export class AppComponent implements OnInit, OnDestroy { constructor(private ngZone: NgZone) {} ngOnInit() { window.my = window.my || {}; window.my.namespace = window.my.namespace || {}; window.my.namespace.publicFunc = this.publicFunc.bind(this); } ngOnDestroy() { window.my.namespace.publicFunc = null; } publicFunc() { this.ngZone.run(() => this.privateFunc()); } privateFunc() { // do private stuff } } 

我还必须为TypeScript添加一个定义来扩展窗口对象。 我把这个放在typings.d.ts中:

 interface Window { my: any; } 

从控制台调用函数现在简单如下:

 my.namespace.publicFunc() 

下面是一个解决scheme。

 function callbackfunction(){ window.angularComponent.runThisFunctionFromOutside(); } <script> System.config({ transpiler: 'typescript', typescriptOptions: { emitDecoratorMetadata: true }, packages: {'js/app': {defaultExtension: 'ts'}} }); System.import('js/app/main') .then(null, console.error.bind(console)); </script> 

我的App.component.ts

 import {Component NgZone} from 'angular2/core'; import {GameButtonsComponent} from './buttons/game-buttons.component'; @Component({ selector: 'my-app', template: ' blblb' }) export class AppComponent { constructor(private _ngZone: NgZone){ window.angularComponent = {runThisFunctionFromOutside: this.runThisFunctionFromOutside, zone: _ngZone}; } runThisFunctionFromOutside(){ console.log("run"); } } 

另一种不使用全局variables的方法是使用传递一个控制对象,并将其属性绑定到要显示的variables和方法。

 export class MyComponentToControlFromOutside implements OnChanges { @Input() // object to bind to internal methods control: { openDialog, closeDialog }; ngOnChanges() { if (this.control) { // bind control methods to internal methods this.control.openDialog = this.internalOpenDialog.bind(this); this.control.closeDialog = this.internalCloseDialog; } } internalOpenDialog(): Observable<boolean> { // ... } internalCloseDialog(result: boolean) { // ... } } 
 export class MyHostComponent { controlObject= {}; } 
 <my-component-to-control [control]="controlObject"></my-component-to-control> <a (click)="controlObject.open()">Call open method</a>