2017-01-20 3 views
6

Я занимаюсь с @Input и @Output, и вот в чем проблема.Изменение значения в двух разных компонентах одновременно Угловое 2

В моем домашнем компоненте я следующее:

<!-- Main Content --> 
<div class="container"> 

    <div *ngIf="registered"> 
     <login></login> 
    </div> 

    <div *ngIf="!registered"> 
     <register></register> 
    </div> 


</div> 

registered расположен в HomeComponent.ts

@Component({ 
    selector:'home', 
    templateUrl:'./home.html', 
}) 

export class HomeComponent { 

    registered:Boolean = true; 

} 

Моя цель состоит в том, чтобы изменить значение registered в домашней компоненте в зависимости от того, что нажата ,

Если в навигационной панели нажата кнопка, форма изменится на регистрационную форму, поскольку значение в home component было изменено. Однако, если логин был нажат, он возвращается.

Я сделал это немного сложнее, но это предназначено для обучения.

В каталоге user У меня есть три модуля, Login, Register и UserService. UserService imports the components from Войти and Регистрация and exports them. I import UserService into Модуль NavigationBar`.

В home.html странице, где я хочу, чтобы изменить формы я просто называю <nav-bar></nav-bar>

@NgModule({ 

    imports:[ 
     SmartAdminModule, 
     UserModule //has Login and Register components 
    ], 

    declarations: [NavigationBarComponent], 
    exports: [NavigationBarComponent] 
}) 
export class NavBarModule { 

} 

Я пытаюсь выяснить способ использовать либо @Output или @Input, чтобы решить эту проблему.

Это также на GitHub HERE Любые советы с положительной оценкой.

---------------- После некоторого совета этого сообщения это так, как я это сделал, но все еще не работает ------------- -----

Я сделал 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); 

    } 

} 

Потом вводят его в 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 
    } 
} 

Тогда у меня был момент, и ага, что я хотел бы сделать кнопки Login и Register и ввести UserService там и тогда, что кнопка будет нажата она изменит значение this.registered = this.userService.registered; в 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; 
    } 


} 

дома ,html

<div class="container"> 

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

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

</div> 

Однако ничего не происходит.

Проект обновлен на GitHub.

+0

Правила большого пальца. Работа с входными и выходными данными в взаимодействии родителей и детей. В качестве входных данных используется сообщение от родительского дочернего элемента. Выход используется при общении с родительским родителем. Так же, как и боковое оповещение;) – Alex

+0

здесь информация о взаимодействии компонентов: https://angular.io/docs/ts/latest/cookbook/component-communication.html Вы можете получить некоторые идеи там. – Alex

ответ

3

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

Исправление должно быть, как это

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); 
    } 
} 

Надежда Я был помочь

PS На притяжении исправлена ​​ошибка с ДИВ не быть закрыт

+0

Это сейчас, но это не работает. Я сделал именно то, что вы сделали. Вы правы, возможно, другое решение было лучше, но я хочу полностью понять '@ Output' и' @ Input', даже если сделать его более сложным, чем необходимо. Я обновил его на GitHub.Я знаю, что вы раздражаетесь этим моментом. Я уверен, что в конце концов я это выясню. – Drew1208

+0

@ Drew1208 не волнуйся, ты получишь, я сделал небольшую ошибку в своем коде, который я обновил. Измените clickEvent в home.component, чтобы emitRegister, так как это результат, который вы тоже привязываете. –

+0

Все еще не работает, но в 'RegisterComponent' он говорит, что' onButtonClick() 'не используется. То же самое для 'LoginComponent' – Drew1208

5

UserService, который вы настроили, находится на месте и наилучшим образом управляет этой переменной, я бы даже зашел так далеко, чтобы поместить методы, которые изменяются с true на false в службе. Таким образом, вы точно знаете, где это контролируется, и если вы используете флаг в другом месте, вы не изменяете эту переменную на случайных компонентах.

@Component({ 
    selector:'nav-bar', 
    templateUrl:'./navigationBar.html', 
}) 
export class NavigationBarComponent{ 

    constructor (private userService: UserService) { } 

    showLogin(){ 
     this.userService.SetUserToRegistered(); 
    } 

    showRegister(){ 
     this.userService.SetUserToUnregistered(); 
    } 
} 

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

Теперь вам нужно наблюдать, чтобы контролировать эту переменную, которую я написал во второй части моего ответа.

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

export class HomeComponent implements OnInit { 

    public registered: boolean = true; 

    public ngOnInit(): void { 
     this.userService.RegisteredObservable().subscribe((registered) => { 
      this.registered = registered; 
     }); 
    } 
} 

Тогда услуга может выглядеть как этот

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); 
    } 
} 
+0

Отличный совет, но можете ли вы посмотреть мой обновленный пост, когда у вас есть время? – Drew1208

+0

@ Drew1208 Я забыл кое-что о наблюдаемой стороне вещей, дайте мне знать, все ли работает нормально. –

+0

Спасибо за ваши усилия. Я попробовал вам решение, но я 'BehaviorSubject ;' дал мне ошибку. Целью этого упражнения была практика '@ Input' и' @ Output'. Пожалуйста, см. Обновление и спасибо за ваше время и жаль позднего ответа. – Drew1208

Смежные вопросы