仅运行一次 Angular 更改检测并停止检测该组件的更改

Amr*_*rit 3 performance typescript angular2-changedetection angular angular-changedetection

我只需要在加载组件或路由发生变化时检测一次角度变化,然后我想停止检测变化。

实际上我需要根据用户角色显示和隐藏功能。所以我*ngIf在一个 html 模板中有很多,但是我只需要在*ngIf第一次加载模板时检查一次条件,然后停止检测更改,因为它会影响性能。

我希望页面在单次更改检测后像静态一样。

例如 :

       <li *ngIf="doesHavePermission('templateName')">
       </li>
Run Code Online (Sandbox Code Playgroud)

应该检查一次,但我看到的是它正在多次检查单身的变化*ngIf,我有很多*ngIf这样的:

我发现markForCheck()detach()这个角文档中https://angular.io/api/core/ChangeDetectorRef

但他们正在做的是他们要么允许所有更改检测,要么根本不允许,

而且我只需要检测一次更改并在此之后停止。

我们可以在角度上进行单次时间变化检测吗?

或者有更好的方法来处理场景吗?

J. *_* S. 5

当您在内部使用函数调用时,*ngIf每次发生更改检测时,angular 都会调用此函数。这个 changeDetection 是在你的组件外部还是内部触发都没有关系,但是 angular 在调用这个函数之前无法知道函数的返回值是否已经改变。

所以*ngIf一般来说在内部使用函数调用并不是一个好方法。

备择方案:

在组件中使用普通属性:

instead of 
<div *ngIf="checkCondition()"></div>

use this

<div *ngIf="condition"></div>

@Component(...)
class MyComponent {
 condition= false;

 checkCondition() {
  if(something) {
   this.condition = true;
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

使用这种方法,您可以在条件发生变化时更好地处理并手动调用该函数。除了使用属性,您还可以使用地图:

@Component(...) 
class MyComponent{
  conditions: { [key: string]: boolean }

  ngOnInit() {
   condition = {
    template1: true,
    template2: false
   }
  }
}

<div *ngIf="conditions['template1']"></div>
Run Code Online (Sandbox Code Playgroud)

ChangeDetectionStrategy.OnPush您结合使用可以最小化onPush更改检测,因为仅在输入参数更改时触发更改检测。这基本上意味着来自父项的更改检测不会触发子项的更改检测。

如果你结合这两种方法,你应该得到最小的变化检测:

@Component({
...
changeDetection: ChangeDetectionStrategy.OnPush
}) 
    class MyComponent{
      @Input() conditions: { [key: string]: boolean }
}
Run Code Online (Sandbox Code Playgroud)

这是一篇可供进一步阅读的好文章:https : //medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496