Angular2-앱 외부에서 구성 요소 함수를 호출하는 방법
콜백이있는 자바 스크립트 개체를 사용하고 있습니다. 콜백이 시작되면 Angular2 구성 요소 내부의 함수를 호출하고 싶습니다.
예제 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>
내 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");
}
App.component.ts 내부에있는 runThisFunctionFromOutside 함수를 어떻게 호출 할 수 있습니까?
Angular 2 메서드를 공개하는 방법 도 참조하세요 .
구성 요소가 구성되면 전역 변수에 자신을 할당합니다. 그런 다음 거기에서 참조하고 메서드를 호출 할 수 있습니다. zone.run(() => { ... })
Angular가 필요한 변경 감지 실행에 대해 알림을 받도록 사용하는 것을 잊지 마십시오 .
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;
}
브라우저 콘솔에서는에서로 전환 <topframe>
해야합니다. plunkerPreviewTarget....
왜냐하면 Plunker가 iFrame
. 그런 다음 실행
window['angularComponentRef'].zone.run(() => {window['angularComponentRef'].component.callFromOutside('1');})
또는
window.angularComponentRef.zone.run(() => {window.angularComponentRef.componentFn('2');})
대안 적 접근
Angular 2-외부 js 라이브러리와 typescript 함수의 통신 에서 설명한 것처럼 Angular 외부에서 이벤트를 전달하고 Angular에서 해당 이벤트를 수신하는 것입니다.
Plunker 예제 2 (댓글에서)
나는 기본적 으로이 대답을 따랐 지만 "외부"코드가 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에 대한 정의를 추가해야했습니다. 나는 이것을 typings.d.ts에 넣습니다.
interface Window { my: any; }
콘솔에서 함수를 호출하는 것은 이제 다음과 같이 간단합니다.
my.namespace.publicFunc()
아래는 해결책입니다.
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>
내 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<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>
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.
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;
};
}
Just adding to @Dave Kennedy:
Calling the function from the console is now as simple as:
my.namespace.publicFunc()
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 of window.my.namespace.publicFunc():
window.opener.my.namespace.publicFunc();
'IT TIP' 카테고리의 다른 글
기본 nginx client_max_body_size (0) | 2020.11.20 |
---|---|
'django_content_type이 이미 존재 함'을 어떻게 해결할 수 있습니까? (0) | 2020.11.20 |
별 5 개 등급으로 정렬하는 더 좋은 방법은 무엇입니까? (0) | 2020.11.20 |
64 비트 Windows에 SciPy를 어떻게 설치합니까? (0) | 2020.11.20 |
C #을 네이티브로 컴파일 하시겠습니까? (0) | 2020.11.20 |