变形检测

Tavish Aggarwal.

 

I

对于知道如何在Angular 2中编写优化应用程序是什么重要的。在这篇文章中,我将解释哪些变更检测以及它在角度上的工作方式。让我们开始。

 

究竟是什么改变检测?

让我们在一个例子的帮助下了解它。假设我们有一个组成部分和视图。每当组件中有任何变化(可能是因为http请求或任何其他因素),也必须在视图中反映。它发生因变化检测而发生。

反之亦然,无论何时有一种变化,也可能是因为必须在组件中反射的输入框。它也会因为改变检测而发生。

变更检测示例

// app.component.ts
class AppComponent {

   data : string;
   myMsg : string;

   constructor(private http: HttpClient) {}

   function updateData(response) {
     this.http.get('//localhost:3002/api/getData')
                        .subscribe(data => { this.data = data; });
   }
}


// app.component.html
<button (click)="open("Change detection occur")">Click me</button>
<p>{{data}}</p>
<p>{[myMsg}}</p>
<input [(ngModel)] ="myMsg" type="text"/>


现在我们知道改变检测是什么。让我们前进,了解变换检测在角2中的工作原理。

简单,一行答案是因为Zone.js.让我们进一步挖掘,并了解Zoous.js在变更检测中的作用是什么。

ZONE.JS.

区域负责:

  • 持久地跨越ASYNC任务执行。
  • 揭示对任务调度和主机环境处理的可见性(范围到当前区域)

区域可用于调试,测试,分析。

假设我们有一个异步函数,即在不同的范围(Web API)中运行的setTimeout,然后在事件循环的帮助下触发执行后触发呼叫堆栈。在此执行期间,异步函数的某些或其他方式不在相同的全局范围内。但等待...... Zone.js是解决方案。考虑下面显示的示例:

zone.fork().run(function() {

   zone.inZone = true;

    setTimeout ( function () {
         console.log("Within set time out " + zone.inZone);
     }, 1000);
});

console.log(zone.inZone);

//Output

false
Within set time out true

我们可以在上面的代码中看到我们有焦点区域.js并添加运行函数。发生在RUN函数内发生的所有执行(同步或异步)都在区域中。由于显而易见的原因,在区域之外发生的执行情况不会在范围内。

从这一点来看,我们可以理解,在角核心文件中,在区域之外写入的所有事件都不会发生变化检测。

在我们的应用程序中触发了通知Zoous.js和更改检测的事件是什么?这些如下所示:

  1. 设置超时,setInterval
  2. XHR调用 - 类似HTTP请求
  3. 点击,mouseover,mousedown等

但是,Zone.js不是你最好的朋友,因为它使用猴子修补。如果您不确定猴子修补的情况,请参阅以下内容:

猴子补丁

假设我们是否有一个具有某些属性和函数的类。当我们在运行时更改属性和函数时,它被称为猴子修补。

ZONE.JS.的问题是它拦截一些像设置超时,事件侦听器和更多的事件。由于我们的应用程序性能可能会降低,如果我们不想拦截此类事件。

因此,在我们的Angular应用程序中明智地使用Zone.js是非常重要的,以避免性能问题。 

不要担心角度服务Ngzone已经照顾了它。 

ngzone. in Angular

Ngzone基本上是一个分叉区域,它扩展了其API并为其执行上下文添加了一些附加功能。它添加的一些事件如下所示:

  • onturnstart() - 在角度开始之前立即通知订阅者。 
  • Onturndone() - 在角度的区域完成处理当前转弯和调度的任何微型任务后立即通知订阅者。
  • OneVentdone() - 在结束VM事件之前,在最终onturndone()回调之后立即通知订阅者。用于测试验证应用程序状态有用。

我们可以根据我们的要求扩展并添加新功能到NGZONE。让我们了解Ngzone提供的RunoutSideAngular函数。

Runoutsideangular.

有时我们不需要在UI中进行更改,或者我们不想触发更改检测。然后Ngzone提供了一种称为RunOueDeAngular以处理此类方案的方法。

如果我们使用RunoutsideAngular函数,那么它并不意味着角度不会知道关于更改的角度。它只提供功能不更新UI的更改。

runoutsideangular的示例:

// app.componenet.ts
this.name = "棱角 change detection";

outsideAngular() {
  this._ngZone.runOutsideAngular(() => {
      this.name = "Changes not reflected in UI";
   });
 }

//app.componenet.html
{{name}}
<button (click)="outsideAngular()"></button>

在上面单击按钮上的代码中,您会注意到UI中没有更改。但是这个属性将获得更新。

在角度改变检测事实

  1. 更改检测始终从根组件到深度节点发生
  2. 由于明显的原因,我们没有像角度1的全球摘要循环。
  3. 我们可以针对我们应用中的每个组件使用不同的更改检测策略,因为我们没有任何全局循环。

检测角度应用程序变化的方法

有三种方法可以控制变化检测。这些是:

  1. 不可变的对象
  2. 使用变更检测策略
  3. exchanceTerectRef.

在一个例子的帮助下,让我们了解以上策略:

不可变的对象 

默认情况下,我们都知道字符串,整数等即使是不可变的。但是,我们有默认情况下的数组和对象不是不可变的。有一个第三方javascript,我们可以使用它来创建对象不可变。

npm install --save immutable

安装后,它在如下所示所示的组件中导入它:

import * as Immutable from 'immutable';

现在我们可以创建不可变的物体,如下所示:

学生 = Immutable.Map({
    firstName: 'Tavish',
    lastName: 'Aggarwal'
})

因此,现在通过创建不变对象,我们无法更新对象属性值。相反,每当我们想要更新我们需要创建对象的新实例时,我们都可以更新值。请参阅下面显示的代码:

this.student = this.student.merge({ firstName: 'Grace', lastName: 'Michael' });

现在只有途方式更新<code>student</code>对象如上所示。 

使用不变对象的优点是变化检测每次都不会运行。相反,现在它将在我们想要的时候具体运行。

使用变更检测策略

角度有两种类型的变化检测策略。这些是:

  • ONPUSH表示将更改检测器的模式设置为检查一次。
  • 默认表示更改检测器的模式将设置为始终检查。

如果我们未指定任何更改检测策略,那么Angular将占用默认值。但要使用Onpush更改检测策略,我们需要指定它,如下所示:

@Component({
  selector: 'my-app',
  template: ``,
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class AppComponent {
}

这将向Angular通知我们的组件仅取决于其输入以及传递给它的任何对象,应视为不可变。 

通过添加ONPUSH更改检测策略,我们显然地向Angular表示,当输入属性更改时,我们的AppComponent仅更改。如果输入属性没有变化,则无需在App Component上运行更改检测。

exchanceTerectRef.

它允许我们从组件附加或删除更改检测。为了更好地控制ONPUSH改变检测策略,我们需要CHNAGENTERECTREF。

让我考虑一个例子:假设输入属性中没有更新,我们使用Onpush改变检测策略,那么也可能是因为某种原因我们需要检测更改。我们如何做到?

答案是换句者。请参阅下面显示的代码:

@Component({
 ...
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
  @Input() data: string;

  constructor(private _cd: ChangeDetectorRef) {}

  refreshContent() {
    this._cd.detectChanges();
  }
}

在上面显示的代码上<code>refreshContent</code>功能,更改检测将运行<code>AppComponent</code>.

我希望你喜欢这篇文章。如果您有任何疑问,请留在评论部分。我将在角度上发布更多的帖子。

作者信息

Tavish Aggarwal.

网站: http://tavishaggarwal.com

Tavish Aggarwal.是一个数据科学家 在一个海德拉巴工作,具有广泛的经验,在跨电子商务,财务,医疗保健等等不同领域解决现实世界的业务问题。 他对技术充满热情,喜欢在团队中工作。

类别