Angular2:如何从父组件到子组件进行通信?

时间:2016-11-10 09:03:11

标签: angularjs angular routing angular-ui-router

我在标签之间加载了一些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加载侧栏和顶栏组件

2 个答案:

答案 0 :(得分:3)

我遇到了那个问题。以下是我解决这种情况的方法;

  • 使用可观察字段创建共享服务,如官方角文档中所述
  • 在导航栏组件中,订阅共享服务中的值以显示导航栏
  • 在登录和注销页面中,更新值。由于您已经订阅了该值,因此订阅者自行处理此情况
  • 创建身份验证服务。添加类似于此的方法来询问您的后端,请求已通过身份验证;
//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);
            });
    }
  • 创建身份验证后卫并在isAuthorizedcanActivatecanLoad中调用CanActivateChild方法。

  • 在回调中,处理未经授权的请求。您可以将用户重定向到错误页面或删除导航栏,以及您想要的任何内容。

我希望它有所帮助!

答案 1 :(得分:1)

我不确定这是否修复了所有内容,但我认为您希望首先从localstorage读取值以获取最近存储的状态,如果使用BehaviorSubject侦听器,则还会获得最后一个状态{{在订阅者订阅之前调用了1}}。

this.subject.emit()