2016-01-04 6 views
5

私はフォームNG1環境に入っていますが、現在、すべての利用可能な機能を備えたNG2アプリケーションを作成しています。私はGoogleとstackoverflowの質問を探求していたが、角度2は非常に速く動いてからapiのアーキテクチャとほとんどの回答が古くなってから運がないと尋ねる前に。Angular2 - 複数のコンポーネントの 'watch'プロバイダープロパティ

私の場合: は、私は、プロパティのユーザーとの認証プロバイダ(サービス)を持って、私は、ユーザーを観察するように、私が試したどのような複数のコンポーネント(ナビゲーションバー、サイドバーなど)

に反応するであろう:

@Injectable(); 
export class Auth { 

    private user; 
    authorized: EventEmitter<boolean>; 

    constructor(public router:Router){ 
     this.authorized = new EventEmitter<boolean>(); 
    } 

    login(user, token):void{ 
     localStorage.setItem('jwt', token); 
     this.user = _.assign(user); 

     this.authorized.emit(<boolean>true); 
     this.router.parent.navigateByUrl('/'); 
    } 
} 


/***************/ 
@Component({...}) 
export class NavComponent { 

    public isAuthroized: boolean = false; 

    constructor(Auth:Auth){ 
     Auth.authorized 
      .subscribe((data) => this.onUserChanged(data)); 
    } 

    onUserChanged(user){ 
     alert('USER:' + user.email); 
     this.isAuthroized = true; 
    } 
} 

/****************/ 
bootstrap(AppComponent, [ 
    ROUTER_PROVIDERS, 
    ELEMENT_PROBE_PROVIDERS, 
    HTTP_PROVIDERS, 
    MapLoader, 
    Auth 
]) 

しかし運がない。 Observable EventEmitterを使うべきでしょうか、あるいはこのケースを扱うための他の正しいアプローチがあるでしょうか? NG1では、サービスのプロパティで$ watchを設定するだけで簡単です。ありがとう!

EDIT: 私は認証サービスに新しいメソッドを追加しました:

... 
userUpdated: EventEmitter<boolean>; 

constructor(public router:Router){ 
    this.userUpdated = new EventEmitter<any>(); 
} 

... 

logout(returnUrl?: string): void{ 
    delete this.user; 
    localStorage.removeItem('jwt'); 
    this.userUpdated.emit(undefined); 

    if(!_.isEmpty(returnUrl)){ 
     this.router.parent.navigateByUrl(returnUrl); 
    } 

} 

そして今イベントは、なぜこれがログアウトのためではなく、ログインのために働いている、と呼ばれていますか?

EDIT 2:

愚かなミスを解決しました

export class LoginPageComponent { 
    error: string; 

    constructor(public http: Http, public router: Router, public Auth:Auth){ 
    } 

    login(event, email, password){ 
     ... 
     this.http.post('/api/login', loginModel, {headers: headers}) 
     .map((res) => res.json()) 
     .subscribe((res: any) => { 
      this.Auth.login(res.user, res.ADM_TOKEN); 
     }, (error) => this.error = error._body); 
    } 

} 

..私は..プロバイダ配列[認証]でNavComponentに残っているので、グローバルな認証とは別の目的であった...ごめんみんな!この問題がAngular2の新しい人に役立つことを願っています。お疲れ様でした。

+0

をだから、あなたの 'onUserChanged'は' Auth.login() 'が呼ばれた後に呼び出されませんか?私はあなたの例の単純なバージョンを再構築しました(ダーツではルーティングとローカルストレージなし)、うまくいきました。 –

+0

まさに!私は@ティエリーのtemplierレスポンスを分析していました。彼と同じコードを持ち、onUserChangedにはまだ警告はありません。 NavComponentをデバッグするとき、subscribeはコンストラクタinitでのみ発生します。 –

+0

最後のコメントが分かりません。あなたの 'NavComponent'は、イベントが発生した後にのみ作成されるでしょうか? –

答えて

1

あなたはすべてのコンポーネントにプロバイダとしてAuthを追加しているとします。これにより、各コンポーネントのクラスの新しいインスタンスが作成されます。 bootstrap(AppComponent, providers: [...])またはAppComponentにのみ追加してください。

1

現在はゾーンによって管理されているため、時計の機能はAngularにはないことがわかります。

他のコンポーネントに通知するには、userUpdatedイベントのAuthサービス内に別のEventEmitterを追加することができます。通知したいコンポーネントは、このエミッタに登録することができます。

@Injectable(); 
export class Auth { 
    private user; 
    authorized: EventEmitter<boolean>; 
    userUpdated: EventEmitter<boolean>; 

    constructor(public router:Router){ 
    this.authorized = new EventEmitter<boolean>(); 
    this.userUpdated = new EventEmitter<boolean>(); 
    } 

    login(user, token):void{ 
    localStorage.setItem('jwt', token); 
    this.user = _.assign(user); 

    this.authorized.emit(<boolean>true); 
    this.userUpdated.emit(this.user); 
    this.router.parent.navigateByUrl('/'); 
    } 
} 

コンポーネントは、このイベントに登録できます。

@Component({...}) 
export class NavComponent { 
    (...) 
    constructor(Auth:Auth){ 
    Auth.userUpdated 
     .subscribe((data) => this.onUserChanged(data)); 
    } 
} 

authorizedイベントを放出するときには、また、ユーザに提供できます。

login(user, token):void{ 
    localStorage.setItem('jwt', token); 
    this.user = _.assign(user); 

    this.authorized.emit(this.user); 
    this.router.parent.navigateByUrl('/'); 
    } 
} 

は、それはあなたのお役に立てば幸い、 ティエリー

+0

これはコンポーネントではなくサービスのプロパティです。コンポーネントがサービスのフィールドが変更されたことをどのように知ることができますか? –

+1

Angular2にはスコープの概念がないので、実際には '$ watch'サポートはありません。他のコンポーネントは 'userChanged'イベントを購読する必要があります。私はそのように答えを更新しました。 –

+1

あなたは 'true'の代わりに' authorized'イベントを送る時にユーザーを提供することもできます.... –

関連する問題