angular2如何检测有状态管道中的更改?

时间:2016-01-11 02:06:36

标签: angular typescript frontend

我基于Angular.io tutorial on pipes

创建了一个简单的有状态管道
@Pipe({
    name: 'fetch',
    pure: false
})

class FetchJsonPipe  implements PipeTransform{
    private fetchedValue = 'waiting';
    private fetchedValue2 = 'waiting2';

    transform(value:string, args:string[]):any {
        setTimeout(() => {
            this.fetchedValue = 'done';
            this.fetchedValue2 = 'done2';
        }, 3000);
        return this.fetchedValue2;
    }
}

@Component({ selector: 'sd-splash'
           , template: 'hello ng2 {{ "5" | fetch }}'
           , pipes: [FetchJsonPipe]
           })

我的问题是,我立即从this.fetchedValue返回#transform。 因为它只是一个字符串,所以它按值返回 。稍后,当超时时 完成后,我只是将值'done'赋给一个属性(也是 私有的)。

Angular2如何知道初始结果'waiting'不是最终结果?怎么样 它是否知道更新的价值将通过#fetchedValue提供? 承诺根本没有暴露,Angular2没有关于名称的信息 我存储结果的字段。

它唯一的线索是pure == false,我猜是指示它 观察实例的变化。但我不知道它是如何获得信息的 要观看哪个字段

但它有效!我不明白为什么。

干杯

2 个答案:

答案 0 :(得分:6)

Angular monkey使用名为Zone.js的库修补浏览器事件(包括setTimeout())。当事件发生时,AngularJS会触发更改检测。

使用有状态管道,AngularJS将在每个事件上重新评估管道,因为即使输入相同,管道结果也可能会发生变化。

使用纯管道,只有当其中一个输入发生变化(即数据进入或args)时,AngularJS才会触发变化检测并重新评估管道。

答案 1 :(得分:2)

为了理解这一点,我认为最好看看Zone.js上的谈话。 基本上angular使用一个名为zone的库在setTimeout调用完成后执行$ rootScope摘要(如果需要)

不仅如此,即使在任何承诺解决之后,也会触发摘要周期。

这正是因为它不知道哪些属性可能已更改,因此脏检查整个应用程序。