简体   繁体   English

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

[英]Run Angular change detection only once and stop detecting changes for that component

I need to detect changes in angular only once when the component is loaded or when route has changed and i want to stop detecting changes after that.我只需要在加载组件或路由发生变化时检测一次角度变化,然后我想停止检测变化。

Actually I need to show and hide functionality depending on user role.实际上我需要根据用户角色显示和隐藏功能。 So i have many *ngIf in a single html template but i need to check *ngIf condition only once when the template is loaded first time and stop detecting changes after that because it is affecting performance.所以我在一个 html 模板中有很多*ngIf但我只需要在模板第一次加载时检查一次*ngIf条件,然后停止检测更改,因为它影响性能。

I want the page to be like static after single time change detection.我希望页面在单次更改检测后像静态一样。

For example :例如 :

       <li *ngIf="doesHavePermission('templateName')">
       </li>

should check once but what I am seeing is that it is checking the change many times for single *ngIf and I have many *ngIf like this:应该检查一次,但我看到的是它正在多次检查单个*ngIf的更改,我有很多*ngIf像这样:

I found markForCheck() and detach() in this angular document https://angular.io/api/core/ChangeDetectorRef .我在这个角度文档https://angular.io/api/core/ChangeDetectorRef 中找到了markForCheck()detach()

But what they are doing is that they are either allowing all change detection or none at all,但他们正在做的是他们要么允许所有更改检测,要么根本不允许,

And I need to detect changes only once and stop after that.而且我只需要检测一次更改并在此之后停止。

Can we do this single time change detection in angular?我们可以在角度上进行单次时间变化检测吗?

Or is there a better way to handle the scenerio?或者有更好的方法来处理场景吗?

When you use a function call inside of *ngIf then angular calls this function every time when change detection occurs.当您在*ngIf使用函数调用时,每次发生更改检测时 angular 都会调用此函数。 It doesn't matter if this changeDetection is triggered outside or inside your component, but angular cannot know if the return value of the function has changed before it has called this function.这个 changeDetection 是在你的组件外部还是内部触发都没有关系,但是 angular 在调用这个函数之前无法知道函数的返回值是否已经改变。

So it is not a good approach to use function calls inside *ngIf in general.因此,通常在*ngIf中使用函数调用并不是一个好方法。

Alternatives:备择方案:

Use normal attributes inside your component:在组件中使用普通属性:

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

use this

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

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

 checkCondition() {
  if(something) {
   this.condition = true;
  }
 }
}

With this approach you can handle better when a condition has changed and call the function manually.使用这种方法,您可以在条件发生变化时更好地处理并手动调用该函数。 Instead of just use an attribute you can also use a map:除了使用属性,您还可以使用地图:

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

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

<div *ngIf="conditions['template1']"></div>

In combination with ChangeDetectionStrategy.OnPush you can minimize the changedetection as onPush only triggers change detection when input params has changed.在与组合ChangeDetectionStrategy.OnPush可以最大限度地减少changedetection作为onPush当输入PARAMS改变才会触发变化检测。 It basically means that change detection from a parent does not trigger change detection of a child.这基本上意味着来自父项的更改检测不会触发子项的更改检测。

If you combine these two approaches you should get minimum changedetection:如果你结合这两种方法,你应该得到最小的变化检测:

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

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

You can just use detach method for ChangeDetectorRef injector to remove current component from Change Detection cycle.您可以只使用ChangeDetectorRef注入器的detach方法从变更检测周期中删除当前组件。 You can always call reattach method or manually call detectChanges to make the quickly run through the changes.您可以随时拨打reattach方法或手动调用detectChanges通过修改,使快速运行。

As for me it's the most reliable way.对我来说,这是最可靠的方式。

But pay attention that it always will turn off change detection for all children!但请注意,它始终会关闭所有孩子的变化检测!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM