我有2个没有任何父子关系的组件。
其中一个组件是一个简单的 login.component.html:
<form #loginForm="ngForm" (ngSubmit)="onSubmit()">
<div class="login-container">
<mat-form-field appearance="fill">
<mat-label>Enter your username</mat-label>
<input
matInput
name="username"
type="text"
[(ngModel)]="username"
#usernameCtrl="ngModel"
required
/>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Enter your password</mat-label>
<input
matInput
name="password"
[type]="hide ? 'password' : 'text'"
[(ngModel)]="password"
#passwordCtrl="ngModel"
required
/>
<button
mat-icon-button
matSuffix
(click)="hide = !hide"
[attr.aria-label]="'Hide password'"
[attr.aria-pressed]="hide"
>
<mat-icon>{{ hide ? "visibility_off" : "visibility" }}</mat-icon>
</button>
</mat-form-field>
</div>
<div>
<button
mat-button
color="primary"
[disabled]="!loginForm.form.valid"
type="submit"
>
Login
</button>
</div>
</form>
另一个是 菜单栏.组件.html:
<div>
<h1>Hello world!</h1>
<h2>I am visible in world all of the time!</h2>
<div *ngIf="loginSuccessfull"> <menu-app> </menu-app> </div>
</div>
当用户成功登录时,我想显示我的menu-app.component。我所做的是定义了一个布尔变量,当用户登录时将其设置为真。
在 登录.组件.ts:
onSubmit() {
if (this.username === 'a' && this.password === 'a') {
console.log('login successful');
this.loginService.updateLoginSuccessfull(true);
}
在 menu-bar.component.ts:
ngOnInit() {
this.loginService.loginSuccessfull.subscribe(loginSuccessfull => this.loginSuccessfull = loginSuccessfull);
}
ngAfterContentChecked() {
this.loginService.loginSuccessfull.subscribe(loginSuccessfull => this.loginSuccessfull = loginSuccessfull);
}
正如你所理解的,两个组件都在调用一个服务,这个服务被定义为 login.service.ts:
export class LoginService {
private onLogin = false;
private onLoginSuccessfull = new BehaviorSubject(this.onLogin);
loginSuccessfull = this.onLoginSuccessfull.asObservable();
constructor() { }
updateLoginSuccessfull(loginSuccessfull: boolean) {
this.onLoginSuccessfull.next(loginSuccessfull);
}
}
我缺少什么?有没有其他方法可以动态地进行这种变化检测?谢谢!预期的行为是显示 <menu-app></menu-app>
只有当用户登录时,才会看到该组件。如果用户没有登录,他应该看不到这个组件。我实现的方式是,即使用户成功登录,也不会显示该组件。
组件看起来很正常 你是否对菜单栏组件使用了OnPush变化检测?你还在菜单栏组件的ngOnInit和ngAfterContentChecked中创建了两个订阅。这将在每次从服务中发出一个值时更新两次loginSuccessful字段。如果你使用的是 async pipe
. 该异步管道可以自动订阅(和取消订阅)Observable,在使用OnPush时将触发变化检测,并减少组件中所需的代码。
menu-bar.component.ts
@Component({
selector: 'menu-bar',
templateUrl: './menu-bar.component.html',
styleUrls: ['./menu-bar.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MenuBarComponent {
loggedIn$ = this.service.loginSuccessful;
constructor(private service: LoginService) { }
}
<div>
<h1>Hello world!</h1>
<h2>I am visible in world all of the time!</h2>
<div *ngIf="loggedIn$ | async"> <menu-app> </menu-app> </div>
</div>