Angular 2

时间:2017-01-20 20:05:47

标签: angular

我正在练习@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登录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
    }
}

然后我有一个aha时刻并且认为我会创建LoginRegister按钮并在那里注入userService然后按下该按钮它会改变{{1}的值在this.registered = this.userService.registered;

NavBar.html

HomeComponent

NavBarComponent:

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

home.html的

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

export class NavigationBarComponent{

    constructor (private userService: UserService) { }


    showLogin(){
        this.userService.registered = true;
    }

    showRegister(){
        this.userService.registered = false;
    }


}

但是没有发生任何事情。

该项目在GitHub上更新。

2 个答案:

答案 0 :(得分: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();
    }
}

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

现在你需要一个observable来监视那个变量,我在答案的第二部分写了这个。

你甚至可以使用一些rxjs并在服务中将变量设置为observable,以便home组件可以订阅它。

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

答案 1 :(得分: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在拉动上修复了div未关闭的问题