我与实践@Input和@Output在这里是问题.
在我的家庭组件中,我有以下内容:
<!-- Main Content -->
<div class="container">
<div *ngIf="registered">
<login></login>
</div>
<div *ngIf="!registered">
<register></register>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
registered 位于 HomeComponent.ts
@Component({
selector:'home',
templateUrl:'./home.html',
})
export class HomeComponent {
registered:Boolean = true;
}
Run Code Online (Sandbox Code Playgroud)
我的目标是registered根据按下的内容更改主组件中的值.
如果在导航栏中按下了注册表单,则表单将更改为注册表单,因为其中的值home component已更改.但是,如果按下登录,它会返回.
我把它变得有点复杂,但这是为了学习目的.
在目录中user我有三个模块Login,Register和UserService.UserService imports the components from登录and注册and exports them. I importUserService intoNavigationBar`模块.
在home.html我想要更改表单的页面中,我只是调用<nav-bar></nav-bar>
@NgModule({
imports:[
SmartAdminModule,
UserModule //has Login and Register components
],
declarations: [NavigationBarComponent],
exports: [NavigationBarComponent]
})
export class NavBarModule {
}
Run Code Online (Sandbox Code Playgroud)
我试图找出一种方法来使用@Output或@Input解决这个问题.
这也是在GitHub 这里 任何建议,非常感谢.
----------------经过这篇文章的一些建议后,我就是这样做的,但仍然无法正常工作----------------- -
我制造了一个 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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我把它注入了 home.module.ts
@NgModule({
imports:[
SmartAdminModule,
UserModule,
NavBarModule
],
exports:[HomeComponent],
declarations: [HomeComponent],
providers: [UserService]
})
export class HomeModule {
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我有一个惊喜的时刻,我想我会做的Login和Register按钮,并在那里注射userService,然后该按钮将被按下它会改变的值this.registered = this.userService.registered;在HomeComponent
NavBar.html
<div>
<button (click)="showRegister()">Register</button>
<button (click)="showLogin()">Login</button>
</div>
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
home.html的
<div class="container">
<div *ngIf="registered">
<login (formUpdate)="handleFormUpdate($event)"></login>
</div>
<div *ngIf="!registered">
<register (formUpdate)="handleFormUpdate($event)"></register>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
然而,什么也没发生.
该项目在GitHub上更新.
您已设置的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();
}
}
Run Code Online (Sandbox Code Playgroud)
也许这些方法可以命名为不同,您可以在扩展应用程序时更好地使用它们,但感觉这是一种更好的方法.
现在你需要一个observable来监视那个变量,我在答案的第二部分写了这个变量.
你甚至可以使用一些rxjs并在服务中将变量设置为observable,以便home组件可以订阅它.
export class HomeComponent implements OnInit {
public registered: boolean = true;
public ngOnInit(): void {
this.userService.RegisteredObservable().subscribe((registered) => {
this.registered = registered;
});
}
}
Run Code Online (Sandbox Code Playgroud)
然后服务可能看起来像这样
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法将使用输入和输出方法,但我会再次尝试实现我的其他答案,因为这是迄今为止最好的解决方案。
修复应该是这样的
首页.html
<div class="container-fluid">
<nav-bar (emitRegistered)="onButtonClicked($event)"></nav-bar>
</div>
Run Code Online (Sandbox Code Playgroud)
主页.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;
}
}
Run Code Online (Sandbox Code Playgroud)
导航Bar.ts
export class NavigationBarComponent{
@Output() emitRegistered: EventEmitter<boolean> = new EventEmitter();
constructor (private userService: UserService) { }
showLogin(){
this.emitRegistered.emit(true);
}
showRegister(){
this.emitRegistered.emit(false);
}
}
Run Code Online (Sandbox Code Playgroud)
希望我能帮上忙
PS On the pull 修复了 div 未关闭的问题
| 归档时间: |
|
| 查看次数: |
3213 次 |
| 最近记录: |