Changing a value simultaneously in two different Angular 2 components

I am training with @Input and @Output and that is the problem.

In my home component, I have the following:

 <!-- Main Content --> <div class="container"> <div *ngIf="registered"> <login></login> </div> <div *ngIf="!registered"> <register></register> </div> </div> 

registered is located in HomeComponent.ts

 @Component({ selector:'home', templateUrl:'./home.html', }) export class HomeComponent { registered:Boolean = true; } 

My goal is to change the registered value in the home component depending on what is clicked.

If a register is pressed in the navigation bar, the form will change to the registration form, because the value in the home component been changed. However, if the login has been pressed, it returns.

I made it a little harder, but it is for learning.

In the user directory, I have three modules: Login , Register and UserService . UserService imports the components from Login and Register and exports them. I import and exports them. I import UserService into Module NavigationBar`.

On the home.html page where I want to change the forms, I just call <nav-bar></nav-bar>

 @NgModule({ imports:[ SmartAdminModule, UserModule //has Login and Register components ], declarations: [NavigationBarComponent], exports: [NavigationBarComponent] }) export class NavBarModule { } 

I am trying to find a way to use either @Output or @Input to solve this problem.

It is also on GitHub HERE Any tips with a great rating.

---------------- After some tips from this post, this is the way I did it, but still does not work -------------- - ---

I made UserService

  @Injectable() export class UserService { public registered: Boolean; @Output() FormUpdate = new EventEmitter(); public SetUserToRegistered(){ this.registered = true; this.FormUpdate.emit(this.registered); } public SetUserToUnregistered(){ this.registered = false; this.FormUpdate.emit(this.registered); } } 

Then I entered it in home.module.ts

 @NgModule({ imports:[ SmartAdminModule, UserModule, NavBarModule ], exports:[HomeComponent], declarations: [HomeComponent], providers: [UserService] }) export class HomeModule { } 

HomeComponent:

  @Component({ selector:'home', templateUrl:'./home.html', }) export class HomeComponent { registered: Boolean; constructor(private userService: UserService) { this.registered = this.userService.registered; } handleFormUpdate(formUpdate){ //what to do here } } 

Then I had an ah-moment, and I thought that I would make the Login and Register buttons and add userService to it, and then this button would be pressed, this would change the value of this.registered = this.userService.registered; in HomeComponent

NavBar.html

 <div> <button (click)="showRegister()">Register</button> <button (click)="showLogin()">Login</button> </div> 

NavBarComponent:

 @Component({ selector:'nav-bar', templateUrl:'./navigationBar.html', }) export class NavigationBarComponent{ constructor (private userService: UserService) { } showLogin(){ this.userService.registered = true; } showRegister(){ this.userService.registered = false; } } 

home.html

 <div class="container"> <div *ngIf="registered"> <login (formUpdate)="handleFormUpdate($event)"></login> </div> <div *ngIf="!registered"> <register (formUpdate)="handleFormUpdate($event)"></register> </div> </div> 

However, nothing happens.

Project updated on GitHub.

+6
source share
2 answers

This approach will use the input and output approach, but I would like to once again begin to execute my other answer, since this is by far the best solution.

The fix should be like this:

home.html

 <div class="container-fluid"> <nav-bar (emitRegistered)="onButtonClicked($event)"></nav-bar> </div> 

home.ts

 export class HomeComponent implements OnInit { public registered: boolean; constructor(private userService: UserService) { } public ngOnInit() { this.registered = true; } protected onButtonClicked(event: boolean) { this.registered = event; } } 

NavigationBar.ts

 export class NavigationBarComponent{ @Output() emitRegistered: EventEmitter<boolean> = new EventEmitter(); constructor (private userService: UserService) { } showLogin(){ this.emitRegistered.emit(true); } showRegister(){ this.emitRegistered.emit(false); } } 

Hope i helped

PS On pushing, the problem with closing the div is fixed

+3
source

The user service you configured is in place and controls this variable in the best way, I would even go so far as to change the methods registered from true to false in the service. This way, you know exactly where this is controlled, and if you use the flag elsewhere, you do not change this variable on random components.

 @Component({ selector:'nav-bar', templateUrl:'./navigationBar.html', }) export class NavigationBarComponent{ constructor (private userService: UserService) { } showLogin(){ this.userService.SetUserToRegistered(); } showRegister(){ this.userService.SetUserToUnregistered(); } } 

Perhaps these methods can be called different, and you can work with them better when expanding your application, but it seems like the best approach.

Now you need to observe to control this variable, which I wrote in the second part of my answer.

You can even use some rxjs and set the variable in the service as observable so that the home component can subscribe to it.

 export class HomeComponent implements OnInit { public registered: boolean = true; public ngOnInit(): void { this.userService.RegisteredObservable().subscribe((registered) => { this.registered = registered; }); } } 

Then the service might look something like this:

 import { Injectable } from "@angular/core"; import { BehaviourSubject } from "rxjs/BehaviourSubject"; import { Observable } from "rxjs/Observable"; @Injectable() export class UserService { private registered: BehaviorSubject<boolean>; constructor() { this.registered = new BehaviourSubject<boolean>(); } public RegisteredObservable(): Observable<boolean> { return this.registered; } public ChangeRegistered() { //do stuff this.registered.next(newRegisteredValue); } } 
+5
source

Source: https://habr.com/ru/post/1014269/


All Articles