如何在UI中进行Angular变化检测?

问题描述 投票:0回答:1

我有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> 只有当用户登录时,才会看到该组件。如果用户没有登录,他应该看不到这个组件。我实现的方式是,即使用户成功登录,也不会显示该组件。

angular angular8 angular-services angular-changedetection dynamic-ui
1个回答
0
投票

组件看起来很正常 你是否对菜单栏组件使用了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>

https:/stackblitz.comeditangular-ivy-pzss5d。

© www.soinside.com 2019 - 2024. All rights reserved.