2017-02-06 7 views
3

초기화 할 때 서비스에서 데이터를 검색하고 배열 인 해당 속성 중 하나를 채우는 클래스가 있습니다. 이 같은 클래스에는 정렬을 필터링하고 반환하는 함수가 있습니다. 이 클래스의 객체를 인스턴스화하고이 함수를 호출하면 해당 생성자와 ngOnInit() 함수가 완료되기 전에 호출 된 것을 알게되었습니다 (아마도 Observables에서 서비스가 반환하는 비동기 컨텐츠를 사용하기 때문에). 내 클래스의 함수가 외부에서 호출되기 전에 생성자와 init이 완전히 실행되도록 어떻게 보장 할 수 있습니까? ,클래스에서 함수를 호출하기 전에 constructor/ngOnInit을 확인하는 방법은 무엇입니까?

export class BaseChoice implements PickAppraiser, OnInit { 
weight = 0; 
options = new Array<PickQuality>(); 

constructor(private championService: ChampionService) {} 

ngOnInit() { 
    // Iterates through the list of champions adding them to the current object 
    this.championService.getChampions() 
     .subscribe(champions => { 
      // Iterates through the list of champions adding them to the current object 
      Object.keys(champions).map(key => this.options.push(new PickQuality(champions[key], 0))) 
     }) 
} 

choose(n?: number): PickQuality[] { 
    var sorted = this.options.sort((a, b) => a.score - b.score); 
    return sorted; 
} 

은}

나는 또한 내가 선택() 메소드 자체 내부의 비동기 요청을 실행

choose(n?: number): PickQuality[] { 
    // Iterates through the list of champions adding them to the current object 
    this.championService.getChampions() 
     .subscribe(champions => { 
      // Iterates through the list of champions adding them to the current object 
      Object.keys(champions).map(key => this.options.push(new PickQuality(champions[key], 0))) 
      this.reevaluate(this.options); 

      var sorted = this.options.sort((a, b) => a.score - b.score); 
      var chosen; 
      if(n) chosen = sorted.slice(1, n); 
      else chosen = sorted.slice(1, 2); 
      return chosen; 
     }); 
} 

그런 짓을하려고했으나 그것은 나를 그렇게 못하게 리턴 변수가 존재한다는 보장이 없기 때문에 가정합니다.

+0

이것은 외부에서 콘텐츠를 호출하는 방법에 따라 달라집니다. 상위 구성 요소, 지시문, 서비스 등에서 호출되고 있습니까? 지도 기능 후에 목록을 정렬 할 수없는 이유가 무엇입니까? – joh04667

+0

[생성자 함수가 Promise를 반환하도록하는 것은 나쁜 습관입니까?] (http://stackoverflow.com/q/24398699/1048572). 인스턴스를 생성하기 전에 인스턴스의 초기화 (생성자 직접 또는 각도 후크를 통해)에서 비동기적인 작업을 수행하지 마십시오. – Bergi

+0

클래스에서 인스턴스를 만들기 전에 어떻게해야합니까? 생성자가 클래스에서 실행되는 첫 번째 것이 아닌가? –

답변

0

options 속성을 빈 배열 options = new Array<PickQuality>();으로 초기화 중이므로 선택 방법에 체크 표시를하지 않으시겠습니까?

choose(n?: number): PickQuality[] { 
    if (this.options && this.options.length !== 0) { 
     var sorted = this.options.sort((a, b) => a.score - b.score); 
     return sorted; 
    } else { 
     /* do something else if options is empty */ 
    } 
} 

--- 편집 --- 여기

내가 코멘트에서 언급 무엇을 대충 버전 : 템플릿에서 (N)를 선택 호출하는 경우

export class BaseChoice implements PickAppraiser, OnInit { 
weight = 0; 
options = new Subject<PickQuality[]>(); 

constructor(private championService: ChampionService) {} 

ngOnInit() { 
    this.championService.getChampions() 
     .subscribe(champions => { 
      Let arr = []; 
      Object.keys(champions).map(key => arr.push(new PickQuality(champions[key], 0))); 
      this.options.next(arr); 
     }) 
} 

choose(n?: number): PickQuality[] { 
    return this.options.take(1).sort((a, b) => a.score - b.score); 
} 
} 
+0

else 문에서 나는 무엇을할까요? 비동기 콘텐츠가 아직 실행되지 않았기 때문에 choose() 함수 호출을 무시할 수는 없습니다. 나도 바쁜 대기 (예 : while (1))에서 내 전체 앱이 중지되는 원인이 될 수 없습니다. –

+0

그게 무슨 선택 메서드와 무엇을하고있다 (당신은 'n'을 통과하지만 사용되지 않습니다)에 따라 달라집니다. 내 애플 리케이션에서 실제로 RXJS 주제를 만들 것입니다. options = new Subject (); 그런 다음 정렬을 선택하고 observable을 반환하면 choose 메서드의 응답 수신자가 배열에 대기 (비동기)합니다. – JRulle

+0

실제로 배열을 options.split (0, n)과 같이 나눠서 사용합니다. 나는이 Subject 물건을 확인해 볼께. 고마워. –

0

* ngIf = "options"을 템플릿의 태그에 추가 할 수 있습니다. "옵션"을 선언하는 방법을 변경해야 데이터가로드 될 때까지 정의되지 않습니다. 이런 식으로 뭔가가 :

options: PickQuality[]; 

당신이 서비스에서 (N)를 선택 호출하는 경우, 내가 대신 관찰 가능한, 또는 약속을 반환하도록 변경한다.

1

필자가 구성 요소를 근본적으로 레이아웃하는 방법을 살펴 봐야한다고 생각합니다. 관측치를 비동기 파이프를 사용하여 템플릿에서 각도를 지원하는 방식으로 활용할 수 있습니다.

나는 구성 요소의 세부 모르겠지만, 이런 걸 할 거라고 : 템플릿에서

export class BaseChoice implements PickAppraiser, OnInit { 
    weight = 0; 
    options$: Observable<PickQuality>; 
    champions$ : Observable<Champion>; 

    constructor(private championService: ChampionService) {} 

    ngOnInit() { 
     this.champions$ = this 
      .championService.getChampions(); 

     this.options$ = this.champions$.map((champion, index) => { 
      return new PickQuality(champion, 0))) 
     }) 
    } 
} 

당신이 *ngFor="let option in options$ | async)을 할 경우는 자동으로 스트림을 실행하고 당신에게 줄 것이다 결과, 사용자가 클릭으로 취하는 동작이라고 가정하는 귀하의 choose() 함수에서, 직접 옵션을 전달하여 그걸로 무언가를 할 수 있습니다.

더 복잡하면 championClicked$과 같은 클릭 스트림에 매핑하고 해당 클릭을 옵션 스트림에서 올바른 옵션으로 매핑하면됩니다.

명심해야 할 점은 파이프 라인을 통해 관측 가능 항목을 설정하고 관측자 (가입자) 당 한 번 파이프 라인이 실행되므로 해당 파이프를 구독하고 실행중인 파이프를 사용할 때마다이를 의미한다는 것입니다. 모든 것.

RxJS에 대해 배우는 데 시간을 투자하면 Angular 2 개발에 큰 성과를 거둘 수 있습니다.