pasar parametros formularios enviar entre ejemplo datos comunicacion componentes componente change angular

parametros - observable angular 4 ejemplo



Angular2: cómo llamar a la función componente desde fuera de la aplicación (6)

A continuación hay una solución.

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>

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){ window.angularComponent = {runThisFunctionFromOutside: this.runThisFunctionFromOutside, zone: _ngZone}; } runThisFunctionFromOutside(){ console.log("run"); } }

Estoy usando un objeto javascript que tiene una devolución de llamada. Una vez que se activa la devolución de llamada, quiero llamar a una función dentro de un componente Angular2.

ejemplo de archivo 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>

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

¿Cómo puedo llamar a la función runThisFunctionFromOutside que está dentro de App.component.ts


Básicamente seguí esta respuesta , pero no quería que mi código "externo" supiera nada sobre NgZone. Esto es 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 } }

También tuve que agregar una definición para TypeScript para extender el objeto de la ventana. Puse esto en typings.d.ts:

interface Window { my: any; }

Llamar a la función desde la consola ahora es tan simple como:

my.namespace.publicFunc()


Consulte también ¿Cómo exponer públicamente los métodos angulares 2?

Cuando se construye el componente, se asigna a una variable global. Luego puede hacer referencia desde allí y llamar a los métodos. No olvide usar zone.run(() => { ... }) para que Angular sea notificado sobre las ejecuciones de detección de cambio requeridas.

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 ejemplo1

En la consola del navegador, debe cambiar de <topframe> a plunkerPreviewTarget.... porque Plunker ejecuta el código en un iFrame . Entonces corre

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

o

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

Un enfoque alternativo

sería enviar eventos fuera de Angular y escucharlos en Angular como se explica en Angular 2: comunicación de funciones de mecanografía con bibliotecas js externas

Plunker example2 (de los comentarios)


Otro enfoque sin usar variables globales es usar pasar un objeto de control y vincular sus propiedades a las variables y métodos para exponer.

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<boolean> { // ... } internalCloseDialog(result: boolean) { // ... } }

export class MyHostComponent { controlObject= {}; }

<my-component-to-control [control]="controlObject"></my-component-to-control> <a (click)="controlObject.open()">Call open method</a>


Solo agrego a @Dave Kennedy :

Llamar a la función desde la consola ahora es tan simple como:

my.namespace.publicFunc()

1) Si intentamos acceder al método público de nuestro componente desde un dominio diferente, quedará atrapado en el problema de CORS (el problema de origen cruzado puede resolverse si tanto el código del servidor como el del cliente residen en la misma máquina).

2) si tuviera que llamar a este método desde el servidor usando javascript, deberá usar window.opener.my.namespace.publicFunc() lugar de window.my.namespace.publicFunc():

window.opener.my.namespace.publicFunc();


Tuve una situación similar al usar la devolución de llamada ''eventClick'' de la biblioteca fullCalendar , cuyas devoluciones de llamada están regresando desde fuera de la zona angular, lo que hace que mi aplicación tenga efectos parciales y poco confiables. Pude combinar el enfoque de zona y una referencia de cierre al componente como se ve a continuación para generar un evento de salida. Una vez que comencé a ejecutar el evento dentro del método zone.run (), el evento y sus efectos fueron una vez más predecibles y detectados por la detección de cambio angular. Espero que esto ayude a alguien.

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; }; }