【问题标题】:Changing a value in two different components at the same time Angular 2同时更改两个不同组件中的值Angular 2
【发布时间】:2017-01-20 20:05:47
【问题描述】:

我正在使用@Input@Output 练习,这就是问题所在。

在我的家庭组件中,我有以下内容:

<!-- 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目录中,我有三个模块,LoginRegisterUserServiceUserService imports the components from LoginandRegisterand exports them. I importUserServiceintoNavigationBar`模块。

home.html 页面中,我想更改我刚刚调用&lt;nav-bar&gt;&lt;/nav-bar&gt; 的表单

@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 {


}

主页组件:

 @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
    }
}

然后我有一个瞬间,我想我会制作LoginRegister 按钮并将userService 注入其中,然后按下该按钮它将更改HomeComponentthis.registered = this.userService.registered; 的值

NavBar.html

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

导航栏组件:

@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>

但是什么都没有发生。

项目已在 GitHub 上更新。

【问题讨论】:

标签: angular


【解决方案1】:

这种方法将使用输入和输出方法,但我会再尝试实施我的其他答案,因为这是迄今为止最好的解决方案。

修复应该是这样的

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 On pull 修复了一个 div 没有被关闭的问题

【讨论】:

  • 这是现在,但它仍然无法正常工作。我做了你所做的。你是对的,也许其他解决方案更好,但我想完全理解@Output@Input,即使它比必要的复杂。我在 GitHub 上更新了它。我知道你对这一点感到恼火。我相信我最终会弄清楚的。
  • @Drew1208 别担心画了你会明白的,我在我更新的代码上犯了一个小错误。将 home.component 中的 clickEvent 更改为 emitRegister,因为这也是您要绑定的输出。
  • 仍然无法正常工作,但 RegisterComponent 中的 onButtonClick() 没有被使用。 LoginComponent也一样
  • @Drew1208 我再次更新,混淆了您可以选择的两个选项,您要实施哪一个?在注册和主页模板上,确保输入具有像这样的 onButtonClick() 的 (click) 方法。
  • 我确实有我的模板。如果你在这里查看我的 GitHub https://github.com/drewjocham/AngularIssue.git,你会发现我正在做你所说的。即使您决定不看,也感谢您的宝贵时间。
【解决方案2】:

您设置的 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();
    }
}

也许这些方法可以命名不同,您可以在扩展应用程序时更好地使用它们,但感觉是一种更好的方法。

现在您需要一个 observable 来监控该变量,我在答案的第二部分中对此进行了说明。

您甚至可以使用一些 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);
    }
}

【讨论】:

  • 很好的建议,但你有时间可以看看我更新的帖子吗?
  • @Drew1208 我忘记了一些可观察的事情,如果一切正常,请告诉我
  • 感谢您的努力。我试过你的解决方案,但我BehaviorSubject&lt;boolean&gt;; 给了我一个错误。本练习的目标是练习@Input@Output。请查看更新,感谢您抽出宝贵时间,对迟到的回复表示歉意。
猜你喜欢
  • 2019-03-09
  • 2018-11-07
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
相关资源
最近更新 更多