簡體   English   中英

Angular2:如何從父組件到子組件進行通信?

[英]Angular2 : How to communicate from parent component to child?

我在標簽之間加載了一些div。 它如吼叫。

這是我的index.html

<html>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>

<!-- 3. Display the application -->

<body>
<my-app>Loading...</my-app>
</body>
</html>

app.module.ts

@NgModule({
imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule
],
declarations: [
    AppComponent,
    LoginComponent,
    HomeComponent,
    NewsfeedComponent,
    TopBarComponent,
    SideMenuComponent
],
providers : [
    AuthGaurd
],
bootstrap: [
    AppComponent
] })
export class AppComponent {}

home.component.ts

@Component({
    selector: 'home',
    moduleId: module.id,
    templateUrl: 'home.component.html',
    providers : [
        LoginService
    ]
})

export class HomeComponent implements OnInit{
isLoggedin : boolean;
constructor (private loginService : LoginService) { }
ngOnInit(): void {
    this.loginService.getLogged().subscribe((isLoggedIn: boolean) => {
        this.isLoggedin = isLoggedIn;
    }); }
}

home.component.html

<side-menu *ngIf='isLoggedin'></side-menu>
<top-bar *ngIf='isLoggedin'></top-bar>
<router-outlet></router-outlet>

auth.gaurd.ts

@Injectable()
export class AuthGaurd implements CanActivate{
    constructor(private router : Router) {
    }
    canActivate(){
        if (localStorage.getItem('isLogin')){
            return true;
        }
        this.router.navigate(['/login'])
        return false;
    }
}

login.service.ts

@Injectable()
export class LoginService {
    private subject: Subject<boolean> = new Subject<boolean>();
    constructor(private router : Router) {
    }
    login(){
        this.setLogged(true);
        localStorage.setItem("isLogin","true");
        this.router.navigate(['/news-feed']);
    }
    logout(){
        this.setLogged(false);
        localStorage.removeItem("isLogin");
        this.router.navigate(['/login']);
    }
    getLogged(): Observable<boolean> {
        return this.subject.asObservable();
    }
    setLogged(val : boolean): void {
        this.subject.next(val);
    }
}

login.component.ts

@Component({
    selector: 'login',
    moduleId: module.id,
    templateUrl: 'login.component.html'
})

export class LoginComponent {
    constructor (private loginService : LoginService) {
    }

    login(){
        this.loginService.login()
    }
}

login.component.html

<input type="number” #mobileNumber />
<input type="password" #password />
<input type="button" (click)="login()">

newsfeed.component.ts

@Component({
    selector: 'newsfeed',
    moduleId: module.id,
    templateUrl: 'newsfeed.component.html',
})

export class NewsfeedComponent {

}

newsfeed.component.html

一些HTML文本.... !!!!

APP-routing.module.ts

@NgModule({
imports: [
    RouterModule.forRoot([
        {
            path : 'login',
            component : LoginComponent
        },
        {
            path : 'news-feed',
            component : NewsfeedComponent,
            canActivate : [AuthGaurd]
        },
        {
            path : '',
            redirectTo : '/news-feed',
            pathMatch : 'full'
        }
        {
            path: '**',
            component: LoginComponent
        }
    ])
],
exports: [
    RouterModule
]
})
export class AppRoutingModule {}

實際上,當我點擊時,它工作正常。 就像它的發布完美而不是單擊登錄按鈕它轉發到新聞源並顯示預期的結果。 但是當我從瀏覽器網址開始時,它不會從home.html加載側欄和頂欄組件

我遇到了那個問題。 這是我如何解決這種情況;

  • 使用可觀察字段創建共享服務,如官方角度文檔中所述
  • 在導航欄組件中,訂閱共享服務中的值以顯示導航欄
  • 在登錄和注銷頁面中,更新值。 由於您已經訂閱了該值,因此訂閱者可以自行處理這種情況
  • 創建身份驗證服務。 添加一個類似於此的方法來詢問您的后端,請求通過身份驗證;
//method parameters depend on what you want
isAuthorized(url: string, errorCallback: (any) => void) {
        let body = JSON.stringify(url)
        return this.http.post('account/isauthorized', body)
            .map((response: Response) => {
                //update value to display navigation bar if user is authenticated
                yourSharedService.observableField.next(true);
                return true;
            })
            .catch((response: Response) => {
                errorCallback(response.status);
                return Observable.of(false);
            });
    }
  • canActivatecanLoadCanActivateChild創建身份驗證保護並調用isAuthorized方法。

  • 在回調中,處理未經授權的請求。 您可以將用戶重定向到錯誤頁面或刪除導航欄,以及您想要的任何內容。

我希望它有所幫助!

我不確定這是否修復了所有內容,但我認為您希望首先從localstorage讀取值以獲取最近存儲的狀態,如果使用BehaviorSubject偵聽器,則如果在調用this.subject.emit()之前也調用了最后一個狀態訂閱者正在訂閱。

@Injectable()
export class LoginService {
    //private subject: Subject<boolean> = new Subject<boolean>(false);
    private subject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(); // <<< changed
    constructor(private router : Router) {
      this.sublect.next(logalStorage.getItem('isLogin')); // <<< added
    }
    login(){
        this.setLogged(true);
        localStorage.setItem("isLogin","true");
        this.router.navigate(['/news-feed']);
    }
    logout(){
        this.setLogged(false);
        localStorage.removeItem("isLogin");
        this.router.navigate(['/login']);
    }
    getLogged(): Observable<boolean> {
        return this.subject.asObservable();
    }
    setLogged(val : boolean): void {
        this.subject.next(val);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM