Angular2 - 如何从应用程序外部调用组件功能

Ron*_*nio 66 angular

我正在使用具有回调的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>
Run Code Online (Sandbox Code Playgroud)

我的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");
}
Run Code Online (Sandbox Code Playgroud)

如何调用App.component.ts中的函数runThisFunctionFromOutside

Dav*_*edy 60

我基本上都遵循了这个答案,但我不希望我的"外部"代码知道关于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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

interface Window { my: any; }
Run Code Online (Sandbox Code Playgroud)

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

my.namespace.publicFunc()
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案并且有效。我认为应该投票为公认的答案。 (3认同)

Gün*_*uer 54

另请参见如何公开公开angular 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;
}
Run Code Online (Sandbox Code Playgroud)

Plunker example1

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

window['angularComponentRef'].zone.run(() => {window['angularComponentRef'].component.callFromOutside('1');})
Run Code Online (Sandbox Code Playgroud)

要么

window.angularComponentRef.zone.run(() => {window.angularComponentRef.componentFn('2');})
Run Code Online (Sandbox Code Playgroud)

另一种方法

将在Angular之外调度事件并在Angular中收听它们,如Angular 2中所述 - 使用外部js库进行打字稿函数的通信

Plunker example2(来自评论)

  • 如果缩小更改名称,则最好分配函数引用而不是类引用(`window.angularComponentRef = {zone:zone,/*component:this*/componentFn:this.callFromOutside};`). (2认同)

Ron*_*nio 6

以下是一个解决方案.

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>
Run Code Online (Sandbox Code Playgroud)

我的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");
    }
}
Run Code Online (Sandbox Code Playgroud)