为什么单击材质工具栏上的任何元素或什至在其外部(其他组件)会导致对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>
答案 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