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
- Создайте новый экземпляр classа с зависимостями, не понимая поставщика фабрики
- Динамическое имя classа внутри ngClass в угловом 2
- Просмотр не обновляется при изменении в Angular2
- Angular2: как связывать для выбора нескольких
- Как передать параметры запроса с помощью routerLink в новом Router V 3 alpha (владивосток)
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
- Как отправить форму на сервер в Angular2?
- Angular2 - * ngFor / цикл через json-объект с массивом
- Angularjs2 - предварительная конфигурация сервера перед запуском приложения
- Ошибка установки углового с использованием npm из-за необходимости использовать строку
- Местоположение и HashLocationStrategy перестали работать в бета-версии.16.
- Итерация над объектом в Угловом
- Проблема с обнаружением изменений. Почему это изменяется, когда это одна и та же ссылка на объект с On Push
- Детальный компонент Angular2 как данные
См. Также Как публиковать угловые методы 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();