Angular 2: событие не срабатывает

Я пытаюсь запустить событие, когда мой компонент получает зарегистрированного пользователя из службы, потому что я хотел бы показывать панель навигации только тогда, когда пользователь вошел в систему.

Вот мой код app.component:

import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import { LoginComponent } from './login.component';
import { DashboardComponent } from './dashboard.component';
import { ControlDetailComponent } from './control-detail.component';
import { PageNotFoundComponent } from './pagenotfound.component';
import { SettingsComponent } from './settings.component';
import { UserService } from '../service/user.service';
import { User } from '../object/user';

@Component({
    selector: 'myApp',
    templateUrl: './app/template/app.component.html',
    styleUrls: ['styles.css'],
    directives: [ROUTER_DIRECTIVES],
    precompile: [LoginComponent, DashboardComponent, ControlDetailComponent, PageNotFoundComponent, SettingsComponent]
})
export class AppComponent {
    @Input() loggedUser:User;
    @Output() userChanged:EventEmitter<User> =  new EventEmitter<User>();

    constructor(private _userService:UserService, private _router:Router) {}

    ngAfterViewInit() { 
        if(this._userService.isUserLogged()) {
           this.userChanged.emit(this._userService.loggedUser);
       }
    }

    switchUser(event) {
        this.loggedUser = event.target.value;
        console.log("event triggered");
    }
}


А это связанный с ним шаблон:

<div class="all-content">
<nav (userChanged)="switchUser($event)" *ngIf="loggedUser">
    <ul>
        <a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
        <a [routerLink]="['/settings']" routerLinkActive="active">Settings</a>
        <a (click)="logout()">Logout</a>
    </ul>
</nav>


Кто-нибудь знает, почему мое событие не запускается?

Первоначально я думал, что проблема заключается в директиве *ngIf, которая предотвращает срабатывание события, но, даже удаляя это, событие все равно не запускается...


person Andrea Caruso    schedule 01.08.2016    source источник


Ответы (2)


События, создаваемые @Output()s, могут быть подписаны только на родительский компонент или директиву, примененную к элементу. У AppComponent нет родительского компонента, поэтому такой подход не сработает.

В вашем случае лучше использовать общий сервис с наблюдаемыми. https://angular.io/docs/ts/latest/cookbook/component-communication.html

person Günter Zöchbauer    schedule 01.08.2016

Решено с помощью Observables и Service, как предложил Günter Zöchbauer (спасибо!).

Ниже моего решения:

user.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { Subject }    from 'rxjs/Subject';
import { Control } from '../object/control';
import { User } from '../object/user';


@Injectable()
export class UserService {
    private userChangedSource = new Subject<User>();
    userChanged = this.userChangedSource.asObservable();
    loggedUser:User;

    userLoggedIn(user:User) {
        this.loggedUser = user;
        this.userChangedSource.next(user);
    }

    ...
}

app.component.ts

import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import { LoginComponent } from './login.component';
import { DashboardComponent } from './dashboard.component';
import { ControlDetailComponent } from './control-detail.component';
import { PageNotFoundComponent } from './pagenotfound.component';
import { SettingsComponent } from './settings.component';
import { UserService } from '../service/user.service';
import { User } from '../object/user';

@Component({
    selector: 'myApp',
    templateUrl: './app/template/app.component.html',
    styleUrls: ['styles.css'],
    directives: [ROUTER_DIRECTIVES],
    precompile: [LoginComponent, DashboardComponent, ControlDetailComponent, PageNotFoundComponent, SettingsComponent]
})
export class AppComponent implements OnInit {
    loggedUser:User;

    constructor(private _userService:UserService, private _router:Router) { 
        this._userService.userChanged.subscribe(user => {
                this.loggedUser = user;
                console.log("event triggered");
        });
    }
    ...
}

app.component.html

<div class="all-content">
    <nav *ngIf="loggedUser" >
        <ul>
            <a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
            <a [routerLink]="['/settings']" routerLinkActive="active">Settings</a>
            <a (click)="logout()">Logout</a>
        </ul>
    </nav>
<router-outlet></router-outlet>
<br/>
</div>
person Andrea Caruso    schedule 01.08.2016