Angular2 – как вызвать функцию компонента извне приложения

Я использую javascript Object, у которого есть обратный вызов. Я хочу, чтобы обратный вызов был вызван для вызова функции внутри компонента Angular2.

пример файла HTML.

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

Мой 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

См. Также Как публиковать угловые методы 2 публично?

Когда компонент сконструирован, он присваивает себе глобальную переменную. Затем вы можете ссылаться на него и называть методы. Не забудьте использовать zone.run(() => { ... }) так что Angular получает уведомление о необходимых zone.run(() => { ... }) обнаружения изменений.

  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

В консоли браузера вам нужно переключиться с на plunkerPreviewTarget.... потому что Plunker выполняет код в iFrame . Затем запустите

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

или

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

Альтернативный подход

было бы направлять события вне углового и слушать их в Угловом, как объяснено в Angular 2 – сообщение функций машинописного текста с внешними js-библиотеками

Пример Plunker2 (из комментариев)

Я в основном следил за этим ответом , но я не хотел, чтобы мой «внешний» код знал что-нибудь о 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 для расширения объекта windows. Я положил это в typings.d.ts:

 interface Window { my: any; } 

Вызов функции с консоли теперь прост как:

 my.namespace.publicFunc() 

Ниже приведено решение.

 function callbackfunction(){ window.angularComponent.runThisFunctionFromOutside(); }  

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

Другой подход, не использующий глобальные переменные, заключается в использовании переданного объекта управления и привязки его свойств к переменным и методам, которые должны быть раскрыты.

 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 { // ... } internalCloseDialog(result: boolean) { // ... } } 
 export class MyHostComponent { controlObject= {}; } 
  Call open method 

У меня была аналогичная ситуация при использовании callback ‘eventClick’ библиотеки fullCalendar , чьи обратные вызовы возвращаются из-за пределов угловой зоны, в результате чего мое приложение имеет частичные и ненадежные эффекты. Мне удалось объединить зонный подход и ссылку на замыкание на компонент, как показано ниже, чтобы поднять выходное событие. Как только я начал выполнять событие внутри метода 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();

  • Как использовать * ngIf else в Angular?
  • Доступ к нескольким просмотрщикам с помощью @viewchild
  • Хранение экземпляра инжектора для использования в компонентах
  • Angular2: приложение аварийно завершает работу / становится невосприимчивым после обнаружения исключения / ошибки
  • Как использовать событие нажатия клавиши в AngularJS?
  • Очистить историю и перезагрузить страницу при входе / выходе из системы с использованием Ionic Framework
  • Как вручную использовать ленивый модуль?
  • Не удается прочитать свойство «push» неопределенного (...) в угловом2
  • Угловая форма 2 для проверки пароля повторения
  • Использование разрешения в Angular2 Routes
  • Передача данных в дочерние компоненты маршрутизатора-выхода (угловые 2)
  • Давайте будем гением компьютера.