Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 - how to call component function from outside the app

Tags:

angular

I am using a javascript Object that has a callback. Once the callback is fired I want to call a function inside an Angular2 component.

example HTML file.

    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> 

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

How can i call the function runThisFunctionFromOutside which is inside App.component.ts

like image 880
Roninio Avatar asked Feb 09 '16 16:02

Roninio


2 Answers

I basically followed this answer, but I didn't want my "outside" code to know anything about NgZone. This is 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   } } 

I also had to add a definition for TypeScript to extend the window object. I put this in typings.d.ts:

interface Window { my: any; } 

Calling the function from the console is now as simple as:

my.namespace.publicFunc() 
like image 102
Big McLargeHuge Avatar answered Sep 20 '22 18:09

Big McLargeHuge


See also How do expose angular 2 methods publicly?

When the component is constucted make it assign itself to a global variable. Then you can reference it from there and call methods. Don't forget to use zone.run(() => { ... }) so Angular gets notified about required change detection runs.

 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

In the browser console you have to switch from <topframe> to plunkerPreviewTarget.... because Plunker executes the code in an iFrame. Then run

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

or

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

An alternative approach

would be to dispatch events outside Angular and listen to them in Angular like explained in Angular 2 - communication of typescript functions with external js libraries

Plunker example2 (from the comments)

like image 42
Günter Zöchbauer Avatar answered Sep 18 '22 18:09

Günter Zöchbauer