I am using a javascript Object that has a callback. I want once the callback is fired 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
Just adding to @Dave Kennedy:
1) If we try to access our component's public method from a different domain you will get caught into CORS issue (the cross origin problem, can be solved if both server and client code resides in same machine).
2) if you were to call this method from server using javascript, you will have to use
window.opener.my.namespace.publicFunc()
instead ofwindow.my.namespace.publicFunc():
window.opener.my.namespace.publicFunc();
I had a similar situation when using the callback 'eventClick' of the fullCalendar library, whose callbacks are returning from outside the angular zone, causing my application to have partial and unreliable effects. I was able to combine the zone approach and a closure reference to the component as seen below in order to raise an output event. Once I started executing the event inside of the zone.run() method the event and it's effects were once again predictable and picked up by angular change detection. Hope this helps someone.
An other approach without using global variables is to use pass a control object and bind its properties to the variables and methods to expose.
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.Plunker example1
In the browser console you have to switch from
<topframe>
toplunkerPreviewTarget....
because Plunker executes the code in aniFrame
. Then runor
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)
I basically followed this answer, but I didn't want my "outside" code to know anything about NgZone. This is app.component.ts:
I also had to add a definition for TypeScript to extend the window object. I put this in typings.d.ts:
Calling the function from the console is now as simple as:
Below is a solution.
My App.component.ts