多次调用ngIf属性-Angular

时间:2018-07-08 14:57:17

标签: angular angular-material

为什么单击材质工具栏上的任何元素或什至在其外部(其他组件)会导致对ngIf属性的多次检查?一个简单的点击可能会导致10-20个通话。简单地填写登录表单就可能导致多达数百个呼叫……这是不正常的,是吗?

也许我通过将<router-outlet></router-outlet>放在材料<mat-sidenav-content></mat-sidenav-content>内来做错了吗?

main-nav.component.html (此组件位于app.component.html中)

  <mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport="true" [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
    [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
    <mat-toolbar color="primary">Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary" class="toolBarContainer">
      <button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()" *ngIf="isHandset$ | async">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span class="likeALink" (click)="onClickLogo()">SimpleCRM</span>
      <p>
        <span id='location'>{{Location}}</span>
      </p>

      <ng-template [ngIf]="!authService.isAuthenticated()">
        <button routerLink="/sign-up" id="sign-up-button" mat-stroked-button>sign-up</button>
        <button routerLink="/sign-in" mat-stroked-button>sign-in</button>
      </ng-template>

      <button class="likeALink" id="logOut" *ngIf="authService.isAuthenticated()" mat-stroked-button (click)="logOut()">log-out</button>

    </mat-toolbar>
    <div>
      <router-outlet></router-outlet>
    </div>
  </mat-sidenav-content>
</mat-sidenav-container>

1 个答案:

答案 0 :(得分:0)

Angular处理模型和dom(组件和模板文件)之间的绑定。为此,应用程序会打勾(更改检测周期)并检查是否有任何值已更改,如果是,则->更新dom。

问题是当模板文件中有函数时,每个循环角度将调用该函数以检查“值”是否已更改。

例如,如果我有一个简单的get函数,该函数仅返回一个值,则Angular需要运行它以检查是否确实存在更改。

{{ myValue() }} // in the template file

myValue() { return 10 } // in the component

在这里有意义的是,角度必须分别调用函数以检查值是否已更改。

一个解决方案(如果您不希望Angular不断调用您的函数),是实现ChangeDectionStrategy(https://angular.io/api/core/ChangeDetectionStrategy)。 这样,您可以告诉Angular您将处理更新,以及更新应在何时运行(仅针对该组件)。

为此,您将在组件元数据中添加以下内容:

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush // the new line
})

然后在构造函数中:

constructor(private changeDetectorRef: ChangeDetectorRef) {}

每当进行更改时,都可以调用 this.changeDetectorRef.markForCheck(); ,该操作将手动运行该组件的周期并在需要时更新dom。

我真的建议您多读一读,因为这个话题太广泛了,无法在这篇文章中描述


另一种解决方案 而不是实现更改检测,而不是使用函数来获取* ngIf的值。您在组件文件中使用公共变量。然后,在更改时将其覆盖。

public authenticated: boolean = false; // use this variable in the template instead of the function

afunction() { // you will have to decide when you can reliably call this
  this.authenticated = isAuthenticated(); 
}

的副本:Angular5 template binding, callback function called more than once