fix(compiler): only call pure pipes if their input changed.

This commit is contained in:
Tobias Bosch
2016-04-21 15:27:51 -07:00
parent bab81a9831
commit 8db62151d2
4 changed files with 78 additions and 9 deletions

View File

@ -491,6 +491,42 @@ export function main() {
expect(renderLog.log).toEqual(['someProp=Megatron']);
}));
it('should call pure pipes only if the arguments change', fakeAsync(() => {
var ctx = _bindSimpleValue('name | countingPipe', Person);
// change from undefined -> null
ctx.componentInstance.name = null;
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual(['null state:0']);
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual(['null state:0']);
// change from null -> some value
ctx.componentInstance.name = 'bob';
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual(['null state:0', 'bob state:1']);
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual(['null state:0', 'bob state:1']);
// change from some value -> some other value
ctx.componentInstance.name = 'bart';
ctx.detectChanges(false);
expect(renderLog.loggedValues)
.toEqual(['null state:0', 'bob state:1', 'bart state:2']);
ctx.detectChanges(false);
expect(renderLog.loggedValues)
.toEqual(['null state:0', 'bob state:1', 'bart state:2']);
}));
it('should call impure pipes on each change detection run', fakeAsync(() => {
var ctx = _bindSimpleValue('name | countingImpurePipe', Person);
ctx.componentInstance.name = 'bob';
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual(['bob state:0']);
ctx.detectChanges(false);
expect(renderLog.loggedValues).toEqual(['bob state:0', 'bob state:1']);
}));
});
describe('event expressions', () => {
@ -1014,6 +1050,7 @@ const ALL_DIRECTIVES = CONST_EXPR([
const ALL_PIPES = CONST_EXPR([
forwardRef(() => CountingPipe),
forwardRef(() => CountingImpurePipe),
forwardRef(() => MultiArgPipe),
forwardRef(() => PipeWithOnDestroy),
forwardRef(() => IdentityPipe),
@ -1089,6 +1126,12 @@ class CountingPipe implements PipeTransform {
transform(value, args = null) { return `${value} state:${this.state ++}`; }
}
@Pipe({name: 'countingImpurePipe', pure: false})
class CountingImpurePipe implements PipeTransform {
state: number = 0;
transform(value, args = null) { return `${value} state:${this.state ++}`; }
}
@Pipe({name: 'pipeWithOnDestroy'})
class PipeWithOnDestroy implements PipeTransform, OnDestroy {
constructor(private directiveLog: DirectiveLog) {}