angular 2 обновляет компонент приложения из компонента выхода маршрутизатора

Я использую angular 2 rc1 и новый маршрутизатор @ angular / router

В компоненте приложения у меня есть раздел навигации и выход маршрутизатора

<nav>   
    <a *ngIf="auth?.userName == null" [routerLink]="['/login']">Login</a>
    <a *ngIf="auth?.userName != null" (click)="logout()">Logout</a>
    {{auth?.userName}}
</nav> 
<router-outlet></router-outlet>

Я ввожу loginService в компонент приложения и подписываюсь на событие в ngOnInit.

ngOnInit() {
    this.loginService.loginSuccess.subscribe(this.loginSuccess);

} 
ngOnDestroy() {
    this.loginService.loginSuccess.unsubscribe();
}
private loginSuccess(res: IAuthResponse) {
    this.auth = res;
}  

когда я перехожу на страницу / компонент маршрута '/ login', мой loginService вводит, а loginService определяет событие

@Output() loginSuccess = new EventEmitter<IAuthResponse>();

и после успешного входа в мою службу служба входа вызывает событие

this.loginSuccess.next(response);

Я могу установить точку останова в компоненте приложения на подписанном loginSucess, и данные будут переданы, однако 'this' не определено.

private loginSuccess(res: IAuthResponse) {
    this.auth = res;  //this is undefind
} 

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


person Dan Soltesz    schedule 12.05.2016    source источник


Ответы (2)


Не уверен, что вы имеете в виду под «и данные переданы».

@Output() loginSuccess = new EventEmitter<IAuthResponse>();

в компоненте, добавленном маршрутизатором (LoginComponent), ничего не делает. @Input() и @Output() в маршрутизируемых компонентах не поддерживаются.

Просто введите LoginService в маршрутизируемый компонент и испустите событие, используя наблюдаемый в компоненте входа в систему.

@Injectable() 
export class LoginService {
  changes:BehaviorSubject = new BehaviorSubject(false);
}
export class LoginComponent {
  constructor(private loginService:LoginService) {}

  onLogin() {
    this.loginService.changes.next(true);
  }
}
export class NavComponent {
  constructor(private loginService:LoginService) {}

  onLogin() {
    this.loginService.changes.subscribe(status => this.isLoggedIn = status);
  }
}
person Günter Zöchbauer    schedule 12.05.2016
comment
Я ввожу loginService в loginComponent, а для loginService определен @output eventEmitter. Когда событие вызывается службой входа в систему, компонент приложения получает событие с данными (IAuthResponse), но 'this' в компоненте приложения имеет значение null / undefined - person Dan Soltesz; 12.05.2016
comment
Хорошо, EventEmitter следует использовать только в компонентах. @Output() в сервисе бессмысленно. У вас где-нибудь в коде есть function() вместо ()=> или вы куда-то передаете функцию? - person Günter Zöchbauer; 12.05.2016
comment
изменение @output () EventEmitter с моей службы на SubjectBehavior привело к правильному поведению, которое я искал. спасибо за пояснение, когда и где использовать выходной атрибут. - person Dan Soltesz; 12.05.2016
comment
Большой! Хорошо, тогда, в конце концов, Behavior' part made the difference. EventEmitter` - это Subject (без Behavior, и команда Angular может в конечном итоге изменить реализацию на что-то другое). Разница в том, что BehaviorSubject немедленно отправляет последнее событие новым подписчикам, в то время как с Subject подписчики получают только события, которые отправляются после того, как они подписались. - person Günter Zöchbauer; 12.05.2016

Похоже, это может быть решением моей проблемы: передача событий от дочернего элемента к родительскому, который использует маршрутизатор-выход, однако похоже, что RC1 изменил принцип работы BehaviorSubject. Используя метод выше:

changes:BehaviorSubject = new BehaviorSubject(false);

выдает ошибку о том, что BehaviorSubject требуется объявление типа, поэтому я попробовал оба

changes:BehaviorSubject<boolean> = new BehaviorSubject(false);
    as well as
changes:BehaviorSubject<any> = new BehaviorSubject(false);

и он компилируется нормально, но при запуске приложения выдает неописательную ошибку:

zone.js:323 SyntaxError: Unexpected token <
Evaluating http://localhost:3000/node_modules/rxjs/index.js
Error loading http://localhost:3000/app/main.js
at SystemJSLoader.__exec
(http://localhost:3000/node_modules/systemjs/dist/system.src.js:1395:16)
at entry.execute 

Я предполагаю, что что-то изменилось с rxjs и BehaviorSubject

person Shar    schedule 24.05.2016
comment
Это не связано с самим BehaviorSubject. Первое сообщение об ошибке - это некоторые настройки конфигурации для проверки статического типа (подробностей здесь я не знаю, потому что сам использую Dart). Второе сообщение об ошибке также связано с настройкой вашего проекта. Пожалуйста, не добавляйте уточняющие вопросы в качестве ответов. Лучше создайте новый вопрос со ссылкой на тот, который вы расширяете. - person Günter Zöchbauer; 24.05.2016
comment
Я узнал, что это было, они переместили местоположение BehaviorSubject. Раньше он находился в rxjs / subject / BehaviorSubject, теперь он исправлен в rxjs / BehaviorSubject. Кроме того, они (Stackoverflow) не позволяют мне добавлять комментарии к другим сообщениям, потому что мне нужен рейтинг 500 или что-то в этом роде, но они позволяют отвечать на сообщения ... - person Shar; 24.05.2016