programing

Angular 2 및 TypeScript 약속

powerit 2023. 6. 7. 23:19
반응형

Angular 2 및 TypeScript 약속

저는 그것을 사용하려고 합니다.routerCanDeactivate내 앱의 구성 요소에 대한 기능..

routerCanDeactivate() {
    return confirm('Are you sure you want to leave this screen?');
}

이것에 대한 유일한 문제는 그것이 못생겼다는 것입니다.브라우저에서 생성된 확인 프롬프트만 사용합니다.부트스트랩 모달과 같은 사용자 지정 모달을 사용하고 싶습니다.부트스트랩 모달이 클릭한 버튼을 기준으로 참 또는 거짓 값을 반환합니다.routerCanDeactivate나는 참/거짓 값 또는 참/거짓으로 해결되는 약속을 수락할 수 있습니다.

▁that▁다▁for▁code▁▁the니가 있는 구성 요소의 코드입니다.routerCanDeactivate방법:

export class MyComponent implements CanDeactivate {
    private promise: Promise<boolean>;

    routerCanDeactivate() {
        $('#modal').modal('show');
        return this.promise;
    }

    handleRespone(res: boolean) {
        if(res) {
            this.promise.resolve(res);
        } else {
            this.promise.reject(res);
        }
    }
}

TypeScript 파일을 컴파일할 때 터미널에서 다음 오류가 발생합니다.

error TS2339: Property 'resolve' does not exist on type 'Promise<boolean>'.
error TS2339: Property 'reject' does not exist on type 'Promise<boolean>'.

구성 요소를 떠나려고 하면 모달이 시작되지만 구성 요소가 비활성화되고 약속이 해결될 때까지 기다리지 않습니다.

하기 위해 입니다.routerCanDeactivate메서드가 약속이 확인될 때까지 기다립니다.없다는 오류가 발생하는 이유가 있습니까?'resolve'Promise<boolean>그 부분을 해결할 수 있다면, 앞으로 무엇을 반환해야 합니까?routerCanDeactivate약속의 해결/해제를 기다리는 방법?

참고로, 여기에 Definite가 있습니다.약속 정의를 입력했습니다.거기에는 분명히 해결 및 거부 기능이 있습니다.

도와주셔서 고마워요.

갱신하다

다음은 Promise가 초기화되는 업데이트된 파일입니다.

private promise: Promise<boolean> = new Promise(
    ( resolve: (res: boolean)=> void, reject: (res: boolean)=> void) => {
        const res: boolean = false;
        resolve(res);
    }
);

리고그고.handleResponse 함수:

handleResponse(res: boolean) {
    console.log('res: ', res);
    this.promise.then(res => {
        console.log('res: ', res);
    });
}

여전히 제대로 작동하지 않지만 모달이 나타나 응답을 기다립니다.Yes leave라고 하면 구성 요소에 남아 있습니다. 첫 또첫번째한.res의 값은 정확합니다..then에 .handleResponse기능.

추가 업데이트

좀 더 읽어보니, 다음과 같습니다.promise선언, 그것은 다음을 설정합니다.resolve 치가, 리고그promise무슨 일이 있어도 그런 가치가 있습니다.그래서 나중에 내가 전화를 해도,.then의 값은 바뀌지 .promise그리고 나는 그것을 실현하고 구성요소를 바꿀 수 없습니다.그것을 만드는 방법이 있습니까?promise기본값이 없으며 다음 값이 될 때까지 기다려야 합니다..then메서드가 호출됩니까?

업데이트된 기능:

private promise: Promise<boolean> = new Promise((resolve, reject) => resolve(false) );

handleResponse(res: any) {
    this.promise.then(val => {
        val = res;
    });
}

도와주셔서 다시 한번 감사드립니다.

마지막 업데이트

많은 제안들을 본 후에, 저는 그것을 만들기로 결심했습니다.Deferredclass.잘를 할 때. 꽤가있었만지할제, ▁class때는가제.deferred.reject(anyType)다음의 콘솔에 오류가 표시됩니다.

EXCEPTION: Error: Uncaught (in promise): null

이와 같은 일이 제가 지나갈 때 일어납니다.null,astring 는또.boolean다음을 제공하려고 합니다.catch에서 합니다.Deferred수업이 안 됐어요

지연된 클래스

export class Deferred<T> {
    promise: Promise<T>;
    resolve: (value?: T | PromiseLike<T>) => void;
    reject:  (reason?: any) => void;

    constructor() {
        this.promise = new Promise<T>((resolve, reject) => {
            this.resolve = resolve;
            this.reject  = reject;
        });
    }
}

부트스트랩 모달 api에 대해서는 잘 모르지만, 생성 시 어떻게든 근접 이벤트에 바인딩할 수 있는 방법이 있을 것으로 예상합니다.

export class MyComponent implements CanDeactivate {

  routerCanDeactivate(): Promise<boolean> {
    let $modal = $('#modal').modal();
    return new Promise<boolean>((resolve, reject) => {
      $modal.on("hidden.bs.modal", result => {
        resolve(result.ok);
      });
      $modal.modal("show");
    });
  }

}

당신은 그것을 사용하려고 합니다.Promise맘에 들다Deferred.Deferred학생들

class Deferred<T> {

  promise: Promise<T>;
  resolve: (value?: T | PromiseLike<T>) => void;
  reject:  (reason?: any) => void;

  constructor() {
    this.promise = new Promise<T>((resolve, reject) => {
      this.resolve = resolve;
      this.reject  = reject;
    });
  }
}

export class MyComponent implements CanDeactivate {

    private deferred = new Deferred<boolean>();

    routerCanDeactivate(): Promise<boolean> {
        $("#modal").modal("show");
        return this.deferred.promise;
    }

    handleRespone(res: boolean): void {
        if (res) {
            this.deferred.resolve(res);
        } else {
            this.deferred.reject(res);
        }
    }
}

Promise에 'resolve' 속성이 없다는 오류가 발생한 이유가 있습니까?

가 네, 그고그 TSC의 수 입니다.es6-promise베타.6에서 ng2 프로젝트의 이러한 문제와 기타 타이핑 문제를 방지하려면 다음을 명시적으로 포함해야 합니다.

///<reference path="node_modules/angular2/typings/browser.d.ts"/>

일반적으로 기본 부트스트랩 파일의 맨 위에서 수행됩니다.*

나머지 질문은 명확하지 않습니다(XY 문제일 가능성이 높습니다. 여기서 x는 위에서 설명한 타이핑 문제입니다).하지만, 당신이 다음과 같은 약속을 정의했다는 것을 이해하는 것이 맞다면,

private promise: Promise<boolean> = new Promise(
    ( resolve: (res: boolean)=> void, reject: (res: boolean)=> void) => {
        const res: boolean = false;
        resolve(res); // <=== how would this ever resolve to anything but false??? 
    }
);

어떻게 이것이 거짓이 아닌 다른 것으로 해결될 것이라고 예상하십니까?

const res: boolean = false;
resolve(res); //always false

와 동등합니다.

resolve(false);  //always false

*참고: 이는 (가능하면) 일시적인 것이며 이후 베타/릴리스 버전에서는 필요하지 않습니다.

사용자의 의견에 따라 업데이트:

handleResponse 기능이 실행되고 해당 응답을 기다리는 방법이 명확하지 않은 것 같습니다.

당신이 여기서 뭘 하려는 건지 아직 잘 모르겠지만, 일반적으로 당신이 원하는 건handleResponse 약속을하이행수다행합니다을음고수다▁return니.

private promise: Promise<boolean> = new Promise((resolve, reject) => {
  handlePromise.then(resultOfHandleResult => {
    //assuming you need to process this result somehow (otherwise this is redundant) 
    const res = doSomethingWith(resultOfHandleResult); 
    resolve(res); 
  })
});

handleResponse(res: any) {
    this.promise.then(val => {
        val = res;
    });
}

또는 (멀리) 관측치를 사용하는 것이 더 좋습니다.

var promise = handleResult() //returns an observable
                .map(resultOfHandleResult => doSomethingWith(resultOfHandleResult))

여기 저에게 효과가 있었던 기술이 있습니다.@iliacchool의 답변과 매우 유사하지만 jQuery 모달 대신 모달 구성 요소를 사용합니다.이것은 다소 더 "Angular 2" 접근법을 만듭니다.저는 그것이 당신의 질문과 여전히 관련이 있다고 믿습니다.

먼저, 모달에 대한 각도 구성요소를 작성합니다.

import {Component, Output, EventEmitter} from '@angular/core;
@Component({
    selector: 'myModal',
    template: `<div class="myModal" [hidden]="showModal">
          <!-- your modal HTML here... -->
          <button type="button" class="btn" (click)="clickedYes()">Yes</button>
          <button type="button" class="btn" (click)="clickedNo()">No</button>
        </div>
    `
})

export class MyModal{
    private hideModal: boolean = true;
    @Output() buttonResultEmitter = new EventEmitter();
    constructor(){}
    openModal(){
        this.hideModal = false;
    }
    closeModal(){
        this.hideModal = true;
    }
    clickedYes(){
        this.buttonResultEmitter.emit(true);
    }
    clickedNo(){
        this.buttonResultEmitter.emit(false);
    }
}

그런 다음 RouterCanDisactivate()가 있는 구성 요소에서 MyModal 인스턴스를 가져와 참조합니다.

import {MyModal} from './myModal';
@Component({
    ....
    directives: [MyModal]
})

클래스 코드:

private myModal: MyModal;

myModal의 Emiter 이벤트에 가입된 약속을 반환하는 메서드를 만듭니다.

userClick(): Promise<boolean> {
    var prom: new Promise<boolean>((resolve, reject) => {
        this.myModal.buttonResultEmitter.subscribe(
            (result) => {
                if (result == true){
                    resolve(true);
                } else {
                    reject(false);
                }
         });
     });
     return prom;
}

마지막으로 RouterCanDisactivate 후크에서 다음을 수행합니다.

routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
    this.myModal.openModal();
    return this.userClick().catch( function(){return false;} );
}

@drewmoore가 언급했듯이, Angular 2에서 관찰 가능한 것을 사용하는 것이 선호되지만, A) 그것은 당신의 질문이 아니었고, B) 라우터CanDetactivehook은 boolean | Promise로 해결되므로, 이 접근 방식이 더 자연스럽게 보였습니다.

모두가 관찰 가능한 것들에 대해 이야기하고 있기 때문에, 저는 @petryuno1의 답변을 보고 기반을 다질 것이라고 생각했습니다.

그의 것부터 시작해서,ModalComponent:

import {Component, Output, ViewChild} from '@angular/core;
@Component({
    selector: 'myModal',
    template: `<div class="myModal" [hidden]="showModal">
          <!-- your modal HTML here... -->
          <button type="button" class="btn" (click)="clickedYes($event)">Yes</button>
          <button type="button" class="btn" (click)="clickedNo($event)">No</button>
        </div>
    `
})

export class MyModal{
    private hideModal: boolean = true;
    private clickStream = new Subject<boolean>();
    @Output() observable = this.clickStream.asObservable();

    constructor(){}
    openModal(){
        this.hideModal = false;
    }
    closeModal(){
        this.hideModal = true;
    }
    clickedYes(){
        this.clickStream.next(true);
    }
    clickedNo(){
        this.clickStream.next(false);
    }
}

는 다으로는, 우리음에 .AppComponent:

import { Component, ViewChild} from '@angular/core';
import {MyModal} from './myModal';
import {Subscription} from "rxjs";

@Component({
    ....
    directives: [MyModal]
})

export class AppComponent {
    @ViewChild(ConfirmModal) confirmModal: ConfirmModal;
    constructor(){...};

    public showModal(){
        this.myModal.openModal();
        this.subscription = this.myModal.observable.subscribe(x => {
            console.log('observable called ' + x)
// unsubscribe is necessary such that the observable doesn't keep racking up listeners
            this.subscription.unsubscribe();
        });
    }
}

관찰 가능한 것의 우아함은 이제 우리가 같은 일을 하기 위해 훨씬 더 적은 코드를 쓸 수 있다는 것입니다.

Angular2+ 월드에서는 s를 사용하여 즉시 실행할 수도 있습니다.

export class MyComponent {
  private subject: Subject<boolean>;

  routerCanDeactivate(): PromiseLike<boolean> {
    $('#modal').modal('show');
    return this.subject.toPromise();
  }

  handleRespone(res: boolean) {
    this.subject.next(res);
  }
}

언급URL : https://stackoverflow.com/questions/36609998/angular-2-and-typescript-promises

반응형