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

我正在使用一个具有回调的 javascript 对象。一旦回调被触发,我想调用 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>

我的 应用程序组件

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");
}

如何调用 App.Component. ts 中的函数 RunThisFunctionFrom 外部

98243 次浏览

参见 如何公开曝光角2方法?

构造组件时,将其自身分配给一个全局变量。然后您可以从那里引用它并调用方法。 不要忘记使用 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;
}

笨蛋例子1

在浏览器控制台中,您必须从 <topframe>切换到 plunkerPreviewTarget....,因为 Plunker 执行 iFrame中的代码。那就快跑

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

或者

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

另一种方法

将派遣事件以外的角度,并听取他们的角度解释了在 角度2-打印函数与外部 js 库的通信

Plunker example2 (来自评论)

下面是一个解决方案。

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>

我的应用程序组件

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");
}
}

我基本上遵循 这个答案,但是我不想让我的“外部”代码知道任何关于 NgZone 的东西:

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 添加一个定义来扩展 window 对象:

interface Window { my: any; }

从控制台调用该函数现在非常简单:

my.namespace.publicFunc()

不使用全局变量的另一种方法是使用传递控件对象并将其属性绑定到要公开的变量和方法。

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>

我在使用 全日历库的回调‘ eventClick’时也遇到过类似的情况,它的回调从角区域外返回,导致我的应用程序产生部分和不可靠的效果。为了引发输出事件,我能够将 zone 方法和对组件的闭包引用组合在一起,如下所示。一旦我开始在 zone.run ()方法内部执行事件,事件和它的效果就可以再次预测,并被角度变化检测所捕获。希望这对谁有帮助。

constructor(public zone: NgZone) { // code removed for clarity
}


ngOnInit() {
this.configureCalendar();
}


private configureCalendar() {
// FullCalendar settings
this.uiConfig = {
calendar: { // code removed for clarity


}
};


this.uiConfig.calendar.eventClick = this.onEventClick();


}


private onEventClick() {
const vm = this;


return function (event, element, view) {
vm.zone.run(() => {
vm.onSequenceSelected.emit(event.sequenceSource);
});


return false;


};
}

@ Dave Kennedy中补充一点:

从控制台调用该函数现在非常简单:

my.namespace.publicFunc()

1) 如果我们试图从不同的域访问组件的公共方法,你会陷入 CORS 问题(如果服务器和客户端代码都位于同一台机器上,跨源问题就可以解决)。

2) 如果你要使用 javascript 从服务器调用这个方法,你必须使用 window.opener.my.namespace.publicFunc()而不是 window.my.namespace.publicFunc():

window.opener.my.namespace.publicFunc();