我正在练习@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
中,我有三个模块,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
}
}
然后我有一个aha时刻并且认为我会创建Login
和Register
按钮并在那里注入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上更新。
答案 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未关闭的问题