2016-11-17 6 views
2

私は正常に動作しないような角度2のサービスを持っています。なんらかの理由でのスコープはであると私は予想していません。私は太い矢印を使用しています。これは物事を正確に維持するはずですが、車輪がどこから落ちているのか分かりません。角2サービスのシングルトンスコープの問題

サービス

declare const Trello: any; 

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 

@Injectable() 
export class TrelloService { 
    key: string = 'test'; 
    token: string = 'test'; 
    boards: any = []; 

    constructor(private http: Http) { 
     console.log('Initializing TrelloService. You should only see me once.'); 
    } 

    getOpenBoards(): Promise<void> { 
     // 'this' is null here. No scope at all??? 
     const url = `https://api.trello.com/1/member/me/boards?key=${this.key}&token=${this.token}`; 
     return this.http.get(url) 
      .toPromise() 
      .then((response: Response) => { 
       debugger; 
       this.boards = response.json(); 
      }); 
    } 
} 

以下のコンポーネントがサービスにgetOpenBoardsを呼び出します。その場合、thisはnullです。これは "クレイジーなjavascriptのスコープの問題"を叫ぶが、私はそれをどうすればいいかわからない。どこでもbindする必要がありますか?もしそうなら、私はどのようにコンポーネントからそれを行うでしょうか?

コンポーネント

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 
import { CatchflyService } from '../../services/catchfly.service'; 
import { TrelloService } from '../../services/trello.service'; 

declare var Trello: any; 

@Component({ 
    selector: 'step-fetch-data', 
    templateUrl: './fetchData.component.html', 
    styleUrls: ['./fetchData.component.scss'] 
}) 
export class FetchDataComponent { 
    showError: boolean = false; 

    constructor(private trelloService: TrelloService, 
       private catchflyService: CatchflyService, 
       private router: Router) { 

     this.catchflyService.getProjects() 
      .then(this.trelloService.getOpenBoards) 
      .then(this.trelloService.getAllLists) 
      .then(() => { 
       console.log('finished getting projects, boards, and lists'); 
      }) 
      .catch((err) => { 
       console.log(err); 
       console.log('service rejected'); 
      }); 
    } 
} 
+0

私はあなたに関連する最終的なメモを追加しました。あなたが編集の通知を受け取ったかどうか分からないので、うまくいけば、このコメントはそのトリックを行います。 – Robba

+0

ノートをありがとう。ええ、彼らはデザインによって連載されています。私はこの質問に出くわす他の人たちがあなたの徹底的な答えを私が持っているものと同じくらい有用だと思っています –

答えて

3

あなたが行うようにあなたがthen機能を呼び出している:

this.catchflyService.getProjects() 
    .then(this.trelloService.getOpenBoards) 
    .then(this.trelloService.getAllLists) 
    .then(() => { 
    console.log('finished getting projects, boards, and lists'); 
    }) 
    .catch((err) => { 
    console.log(err); 
    console.log('service rejected'); 
}); 

あなたはそれはそれはそれは上のオブジェクトに結合します失います基準とgetOpenBoards機能を渡しています。

1:ハンドラに直接関数を呼び出します。

this.catchflyService.getProjects() 
    .then(i => this.trelloService.getOpenBoards()) 
    .then(i => this.trelloService.getAllLists()) 
    .then(() => { 
    console.log('finished getting projects, boards, and lists'); 
    }) 
    .catch((err) => { 
    console.log(err); 
    console.log('service rejected'); 
}); 

2:あなたは、2つのいずれかを行うことができます

this.catchflyService.getProjects() 
    .then(this.trelloService.getOpenBoards.bind(this.trelloService)) 
    .then(this.trelloService.getAllLists.bind(this.trelloService)) 
    .then(() => { 
    console.log('finished getting projects, boards, and lists'); 
    }) 
    .catch((err) => { 
    console.log(err); 
    console.log('service rejected'); 
}); 

:それを渡すときに機能をバインド編集

最終的なメモ。ここでは、依存関係のない3つの非同期メソッドを呼び出しています(thenに渡される関数へのパラメータがないため)。 then関数を連鎖させる方法のため、それらは順番に呼び出されます。 3つの呼び出しの間に依存関係がない場合は、コードを並列に呼び出してさらに最適化することができます:

var p1 = this.catchflyService.getProjects(); 
var p2 = this.trelloService.getOpenBoards(); 
var p3 = this.trelloService.getAllLists(); 

Promise.all([p1,p2,p3]) 
    .then(() => { 
    console.log('finished getting projects, boards, and lists'); 
    }) 
    .catch((err) => { 
    console.log(err); 
    console.log('service rejected'); 
}); 
+0

TSの観点から見ると、 'bind'はまだ安全ではないタイプなので、より良いです。 – estus

+0

私は同意し、常に方法1を使用しますが、問題のコードがなぜ機能しないのかを具体的に説明するだけであれば、言及すべきであると感じました。 – Robba

2

試行分割次いで.then()は関数を呼び出します。

export class FetchDataComponent 
{ 
    showError: boolean = false; 

    constructor(private trelloService: TrelloService, 
       private catchflyService: CatchflyService, 
       private router: Router) 
    { 

     this.catchflyService.getProjects() 
      .then(()=> 
      { 
       this.trelloService.getOpenBoards() 
      }) 
      .then(()=> 
      { 
       this.trelloService.getAllLists() 
      }) 
      .then(() => 
      { 
       console.log('finished getting projects, boards, and lists'); 
      }) 
      .catch((err) => 
      { 
       console.log(err); 
       console.log('service rejected'); 
      }); 
    } 
}