programing

Angular2 - 앱 외부에서 컴포넌트 기능 호출 방법

oldcodes 2023. 9. 16. 09:53
반응형

Angular2 - 앱 외부에서 컴포넌트 기능 호출 방법

콜백이 있는 자바스크립트 Object를 사용하고 있습니다.콜백이 실행되면 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>

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

App.component.ts 내부에 있는 runThisFunctionFromoutside 함수를 어떻게 호출할 수 있습니까?

저는 기본적으로 이 답변을 따랐지만, "외부" 코드가 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 정의도 추가해야 했습니다.이것을 타이핑.d.ts에 입력했습니다.

interface Window { my: any; }

콘솔에서 기능을 호출하는 것은 이제 다음과 같이 간단합니다.

my.namespace.publicFunc()

참고 항목각도 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;
}

플렁커 예제1

브라우저 콘솔에서 전환해야 합니다.<topframe>로.plunkerPreviewTarget....플렁커가 코드를 실행하기 때문에iFrame. 그다음달리기

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

아니면

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

대안적 접근법

Angular 2에서 설명한 것처럼 Angular 외부의 이벤트를 전송하고 Angular에서 듣는 것입니다 - 외부 js 라이브러리와 타이프스크립트 함수의 통신.

플렁커 예제 2 (댓글에서)

아래는 해결 방법입니다.

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

전역 변수를 사용하지 않는 또 다른 방법은 pass control object를 사용하고 속성을 변수와 메서드에 바인딩하여 노출하는 것입니다.

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>

전체 캘린더 라이브러리의 콜백 'eventClick'을 사용할 때도 유사한 상황이 있었는데, 앵글 존 밖에서 콜백이 반환되어 애플리케이션이 부분적이고 신뢰할 수 없는 영향을 받게 되었습니다.아래와 같이 Zone approach와 구성요소에 대한 Closure reference를 결합하여 출력 이벤트를 발생시킬 수 있었습니다.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();

언급URL : https://stackoverflow.com/questions/35296704/angular2-how-to-call-component-function-from-outside-the-app

반응형