feat(pipes): add support for pure pipes

By default, pipes are pure. This means that an instance of a pipe will be reused and the pipe will be called only when its arguments change.

BREAKING CHANGE

Before:

@Pipe({name: 'date'}) class DatePipe {} defines an impure pipe.

After:

@Pipe({name: 'date'}) class DatePipe {} defines a pure pipe.
@Pipe({name: 'date', pure: false}) class DatePipe {} defines an impure pipe.

Closes #3966
This commit is contained in:
vsavkin
2015-09-08 09:17:58 -07:00
committed by Victor Savkin
parent 5a59e8be82
commit a8bdb693b9
16 changed files with 167 additions and 74 deletions

View File

@ -59,7 +59,7 @@ var _observableStrategy = new ObservableStrategy();
*
* ```
*/
@Pipe({name: 'async'})
@Pipe({name: 'async', pure: false})
@Injectable()
export class AsyncPipe implements PipeTransform, PipeOnDestroy {
_latestValue: Object = null;

View File

@ -4,14 +4,15 @@ import {Key, ResolvedBinding, Binding} from 'angular2/src/core/di';
import {PipeMetadata} from '../metadata/directives';
export class PipeBinding extends ResolvedBinding {
constructor(public name: string, key: Key, resolvedFactories: ResolvedFactory[],
multiBinding: boolean) {
constructor(public name: string, public pure: boolean, key: Key,
resolvedFactories: ResolvedFactory[], multiBinding: boolean) {
super(key, resolvedFactories, multiBinding);
}
static createFromType(type: Type, metadata: PipeMetadata): PipeBinding {
var binding = new Binding(type, {toClass: type});
var rb = resolveBinding(binding);
return new PipeBinding(metadata.name, rb.key, rb.resolvedFactories, rb.multiBinding);
return new PipeBinding(metadata.name, metadata.pure, rb.key, rb.resolvedFactories,
rb.multiBinding);
}
}

View File

@ -1,4 +1,5 @@
import {isBlank, isPresent, BaseException, CONST, Type} from 'angular2/src/core/facade/lang';
import {StringMapWrapper} from 'angular2/src/core/facade/collection';
import {
Injectable,
OptionalMetadata,
@ -25,11 +26,25 @@ export class ProtoPipes {
}
}
export class Pipes implements cd.Pipes {
_config: StringMap<string, cd.SelectedPipe> = {};
constructor(public proto: ProtoPipes, public injector: Injector) {}
get(name: string): any {
var b = this.proto.get(name);
return this.injector.instantiateResolved(b);
get(name: string): cd.SelectedPipe {
var cached = StringMapWrapper.get(this._config, name);
if (isPresent(cached)) return cached;
var p = this.proto.get(name);
var transform = this.injector.instantiateResolved(p);
var res = new cd.SelectedPipe(transform, p.pure);
if (p.pure) {
StringMapWrapper.set(this._config, name, res);
}
return res;
}
}