angular2 Component間データ受け渡し メモ

anguler2のチュートリアルを改造していて、
serviceで実行したHTTP POST通信の処理結果によって、
呼び出し元componentの画面を変更したくなった。

angular2 - Global Events in Angular 2 - Stack Overflow

Service Events というものがあるらしい。

my app

@Output() loginError = new EventEmitter();
を足して、
イベントを発生させたい(呼び出し元componentの関数を実行したい)タイミングで、
this.loginError.emit("Error:server returns false");
のようにevent emit

service.ts

import {Injectable} from 'angular2/core';
import {Output, EventEmitter} from 'angular2/core';
import {URLSearchParams, Headers, Http, Response} from 'angular2/http';
import {Router} from 'angular2/router';
import {Observable} from 'rxjs/Rx';

export interface LoginResult {
    result: string;
    username: string;
}

@Injectable()
export class LoginService {
  
  @Output() loginError = new EventEmitter<string>();
  
  private loginRes: LoginResult;
  
  constructor(private http: Http, private _router: Router) {}
  
  login (username: string, password: string) {
      let res = this._query(username, password);
      res.subscribe(
          updatedLogin => { this.loginRes = updatedLogin },
          error => console.log('Error login (http post)'),
          () => {
              // onCompleted
              this._after_query()
          }
      );
      
      // undefined error
      // console.log("username:" + this.loginRes.username);
  }
  
  private _after_query() {
      console.log("username:" + this.loginRes.username);
      console.log("result:" + this.loginRes.result);
      
      if(this.loginRes.result == 'true'){
        let link = ['Dashboard'];
        this._router.navigate(link);
      }else{
          // TODO:
          console.log('emit login failed event');
          this.loginError.emit("Error:server returns false");
      }
  }
  
  private _query(username, password):Observable<LoginResult> {
      let url = '/mock_login';
      var params = new URLSearchParams();
      params.set('action', 'login');
      params.set('username', username);
      params.set('password', password);
      let headers = new Headers();
      //headers.append('Content-Type', 'application/json');
      headers.append('Content-Type', 'application/x-www-form-urlencoded');
      
      return this.http.post(url, params.toString(), {
        headers: headers
        })
        .map((res:Response) => res.json());
  }
}

constructorでevent登録。
_loginService.loginError.subscribe( message =>this.onLoginError(message) );
event処理本体。
onLoginError(message){

component.ts

import { Component, View } from 'angular2/core';

import { Http, Headers, Response } from 'angular2/http';
import {JSONP_PROVIDERS}  from 'angular2/http';
import {Observable}       from 'rxjs/Observable';

import {LoginService} from './login.service';


import { Router, RouterLink } from 'angular2/router';
import { CORE_DIRECTIVES, FORM_DIRECTIVES } from 'angular2/common';
import { contentHeaders } from '../../app/common/headers';

import {Hero}           from '../hero';

@Component({
  selector: 'login',
  templateUrl: 'app/login/login.component.html',
  styleUrls: ['app/login/login.component.css'],
  providers:[JSONP_PROVIDERS, LoginService]
})

export class LoginComponent {
  constructor(public router: Router, public http: Http, private _loginService: LoginService) {
      _loginService.loginError.subscribe( message =>this.onLoginError(message) );
  }
  
  results: Observable<string[]>;
  loginErrorMessage: string;

  login (username: string, password: string) {
    this._loginService.login(username, password);
    //this._loginService.login2(username, password);
  }

  onLoginError(message){
      // event fired from login.service.ts
      console.log('login failed');
      console.log(message);

      // TODO: Display error message
      this.loginErrorMessage = message;
  }
}

How to do inter communication between a master and detail component in Angular2? - Stack Overflow

Angular 2 @Outputのアレコレ - Qiita