2016-05-19 15 views
3

SidebarComponentのコンポーネント変数 'user'が更新された後に{{user.email}}が更新されないのを見る。マニュアルページの更新後に動作します。 材料設計を別のコンポーネントに分割しました。コンポーネント変数がAngular2で変更された後にビューが更新されない

SidebarComponent.ts

import {Component} from 'angular2/core'; 
import {Router, RouteConfig, ROUTER_DIRECTIVES,CanActivate} from 'angular2/router'; 
import {HomeComponent} from '../home/HomeComponent' 
import {DashboardComponent} from './DashboardComponent' 

@Component({ 
    selector: 'app-sidebar', 
    template: ` 
     <header class="demo-drawer-header"> 
      <img src="../app/assets/images/user.jpg" class="demo-avatar"> 
      <div class="demo-avatar-dropdown"> 
      <span>{{user.email}}</span> 
      <div class="mdl-layout-spacer"></div> 
      <button id="accbtn" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"> 
       <i class="material-icons" role="presentation">arrow_drop_down</i> 
       <span class="visuallyhidden">Accounts</span> 
      </button> 
      <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="accbtn"> 
       <li class="mdl-menu__item">[email protected]</li> 
       <li class="mdl-menu__item">[email protected]</li> 
       <li class="mdl-menu__item"><i class="material-icons">add</i>Add another account...</li> 
      </ul> 
      </div> 
     </header> 
     <nav class="demo-navigation mdl-navigation mdl-color--blue-grey-800"> 

      <a class="mdl-navigation__link" [routerLink]="['./Dashboard']"><i class="mdl-color-text--blue- grey-400 material-icons" role="presentation">dashboard</i>Dashboard</a> 


      <a class="mdl-navigation__link" [routerLink]="['./Home']"><i class="mdl-color-text--blue-grey-400  material-icons" role="presentation">assignment</i>Tasks</a> 

      <a class="mdl-navigation__link" href=""><i class="mdl-color-text--blue-grey-400 material-icons"  role="presentation">delete</i>Trash</a> 
     </nav> 
    `, 

    directives: [ROUTER_DIRECTIVES,DashboardComponent] 
}) 

export class SidebarComponent { 

    user = JSON.parse(localStorage.getItem('profile')); 

    constructor() {} 

}

Iは

import {Directive, DynamicComponentLoader, ElementRef} from "angular2/core"; 
import {AuthService} from '../../services/AuthService' 
import {Router, RouterOutlet, ComponentInstruction} from "angular2/router"; 

@Directive({ 
    selector: 'auth-router-outlet' 
}) 
export class AuthRouterOutlet extends RouterOutlet { 
    private _protectedRoutes = { 
     'app/**': true, 
     'app/home': true, 
     'app/dashboard': true, 
     'app/about': true 
    }; 

    constructor(_elementRef: ElementRef, _loader: DynamicComponentLoader, private _router: Router, nameAttr:  string, private _authService: AuthService) { 
     super(_elementRef, _loader, _router, nameAttr); 
    } 

    activate(nextInstruction: ComponentInstruction): Promise<any> { 
     if (this._protectedRoutes[nextInstruction.urlPath]) {   
      if (!this._authService.loggedIn()) { 
       this._router.navigate(['Login']); 
      } 
     } 

     return super.activate(nextInstruction); 
    } 
} 

aboue以下の通りであるユーザの認証を確認するために、カスタムルータ出口を有しているが、以下のようにサイドバーの成分でありますアウトレットは、LocalstorageにProfileオブジェクトを設定する次のAuthservice.tsを使用します。

import {Injectable} from 'angular2/core'; 
import {ROUTER_DIRECTIVES, Router} from "angular2/router"; 
import {tokenNotExpired} from 'angular2-jwt'; 


declare var Auth0Lock: any; 

@Injectable() 
export class AuthService { 

constructor(private router: Router) {} 

    private useremail; 

    lock = new Auth0Lock('KEY','URL'); 

    login() { 
    this.lock.show((error: string, profile: Object, id_token: string) => { 
    if (error) { 
     console.log(error); 
     return false; 
    } 

    localStorage.setItem('profile', JSON.stringify(profile)); 
    localStorage.setItem('id_token', id_token); 

    /*var profiletemp = JSON.parse(localStorage.getItem('profile')); 
    this.setUserEmail(profiletemp.email);*/ 

    this.router.navigate(['Dashboard']); 

    }); 
} 

logout() { 
    localStorage.removeItem('profile'); 
    localStorage.removeItem('id_token'); 
} 

loggedIn() { 
    return tokenNotExpired(); 
    } 

/* setUserEmail(val) {   -- not required as profile object is in localstorage 
     this.useremail = val; 
    } 

getUserEmail() { 
     return this.useremail; 
    } */ 
} 

index.htmlを

<html> 
    <head> 
    <title>MEAN</title> 
    <base href="/"/> 

    <!-- 1. Load libraries --> 
    <script src="libs/angular2/bundles/angular2-polyfills.js"></script> 
    <script src="libs/systemjs/dist/system.src.js"></script> 


    <script src="libs/rxjs/bundles/Rx.js"></script> 
    <script src="libs/angular2/bundles/angular2.dev.js"></script> 
    <script src="libs/angular2/bundles/router.dev.js"></script> 
    <script src="//cdn.auth0.com/js/lock-9.0.min.js"></script> 
    <script src="libs/angular2/bundles/http.dev.js"></script> 
    <script src="https://code.getmdl.io/1.1.3/material.min.js"></script> 

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"></ meta> 

    <meta name="mobile-web-app-capable" content="yes"> 
    <link rel="icon" sizes="192x192" href="app/assets/images/android-desktop.png"></meta> 

    <!-- Add to homescreen for Safari on iOS --> 
    <meta name="apple-mobile-web-app-capable" content="yes"></meta> 
    <meta name="apple-mobile-web-app-status-bar-style" content="black"></meta> 
    <meta name="apple-mobile-web-app-title" content="Material Design Lite"></meta> 
    <link rel="apple-touch-icon-precomposed" href="app/assets/images/ios-desktop.png"> 

    <!-- Tile icon for Win8 (144x144 + tile color) --> 
    <meta name="msapplication-TileImage" content="app/assets/images/touch/ms-touch-icon-144x144-precomposed.png">< /meta> 
    <meta name="msapplication-TileColor" content="#3372DF"></meta> 

    <link rel="shortcut icon" href="app/assets/images/favicon.png"> 


    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light, bolditalic,black,medium&amp;lang=en"> 
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> 
    <link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.cyan-light_blue.min.css"> 
    <link rel="stylesheet" href="app/assets/styles.css"> 
    <style> 
    #view-source { 
     position: fixed; 
     display: block; 
     right: 0; 
     bottom: 0; 
     margin-right: 40px; 
     margin-bottom: 40px; 
     z-index: 900; 
    } 
    </style> 

    <!-- 2. Configure SystemJS --> 
    <script> 
     System.config({ 
     packages: {   
      app: { 
      format: 'register', 
      defaultExtension: 'js' 
      } 
     } , 
     map: { 
      "angular2-jwt": "libs/angular2-jwt/angular2-jwt.js" 
     } 
     }); 
     System.import('app/bootstrap') 
      .then(null, console.error.bind(console)); 
    </script> 

    </head> 
    <!-- 3. Display the application..All ExpressJS requests come to this index file and from here Angular routing  takes over--> 
    <body> 
    <my-app>Loading the application...</my-app> 
    </body> 

</html>  

私はangular2-polyfills.jsがインデックスに含まれています。 SidebarComponentビューは、コンポーネント内の対応する変数が変更された後に更新されません。

アイデア?

答えて

4

ような何か共有サービスAuthServiceでのローカルストレージアプリケーションのブートストラップ時にこのサービスが設定されていることを確認してください。あなたが通知され、対応するテンプレートを更新することがprofileUpdated $で購読することができますSidebarComponentコンポーネント内

constructor(private router: Router) {} 
    private useremail; 
    profileUpdated$:Suject<any> = new Subject(); // <------- 

    lock = new Auth0Lock('KEY','URL'); 

    login() { 
    this.lock.show((error: string, profile: Object, id_token: string) => { 
     if (error) { 
     console.log(error); 
     return false; 
     } 

     localStorage.setItem('profile', JSON.stringify(profile)); 
     localStorage.setItem('id_token', id_token); 
     this.profileUpdated$.next(profile); // <------- 

     this.router.navigate(['Dashboard']); 
    }); 
} 

logout() { 
    localStorage.removeItem('profile'); 
    localStorage.removeItem('id_token'); 
    this.profileUpdated$.next(null); // <------- 
} 

@Component({ 
    (...) 
}) 
export class SidebarComponent { 

    user = JSON.parse(localStorage.getItem('profile')); 

    constructor(private service:AuthService) { 
    this.profileUpdated$.subscribe(profile => { // <----- 
     this.user = profile; 
    }); 
    } 
+0

まだ同じ動作です。サイドバーをリロードするには、手動でページを更新する必要があります。 – user2180794

+0

コールバックは 'SidebarComponent'コンポーネント内で呼び出されますか? 'AuthService'サービスはアプリケーションのブートストラップ時にのみ定義されます(コンポーネントの' providers'属性ではない)? –

+0

私はサイドバーコンポーネントのコールバックについてよく分かりませんか? AuthServiceはブートストラップにのみあり、どのコンポーネントのプロバイダにもありません。 – user2180794

0

返品はlocalStorage.getItem('profile')です。

user = JSON.parse(localStorage.getItem('profile')); 

あなたが最初のユーザモデルを作成し、このモデルにjson resultを割り当てる必要があります。私はあなたがprofileが以内に更新されたSidebarComponentコンポーネントに通知する必要があると思います。この

User.ts

export class User { 
    email:string; 
} 

変更SidebarComponent.tsクラス

export class SidebarComponent { 
    user:User ; 
    constructor() { 
    this.user=JSON.parse(localStorage.getItem('profile')); 
    } 
} 
+0

私はそれを行う場合でも、私は、ログインした後、サイドバーのコンストラクタが呼び出されません。したがって、ログインする前にサイドバーが既にロードされています。そのため、ページを更新すると、すべて正常に動作します。 – user2180794

関連する問題