diff --git a/modules/angular2/src/common/pipes/async_pipe.ts b/modules/angular2/src/common/pipes/async_pipe.ts index 5842caa34b..51e31784fa 100644 --- a/modules/angular2/src/common/pipes/async_pipe.ts +++ b/modules/angular2/src/common/pipes/async_pipe.ts @@ -4,7 +4,7 @@ import { Pipe, Injectable, ChangeDetectorRef, - PipeOnDestroy, + OnDestroy, PipeTransform, WrappedValue } from 'angular2/core'; @@ -55,7 +55,7 @@ var _observableStrategy = new ObservableStrategy(); */ @Pipe({name: 'async', pure: false}) @Injectable() -export class AsyncPipe implements PipeTransform, PipeOnDestroy { +export class AsyncPipe implements PipeTransform, OnDestroy { /** @internal */ _latestValue: Object = null; /** @internal */ @@ -70,7 +70,7 @@ export class AsyncPipe implements PipeTransform, PipeOnDestroy { public _ref: ChangeDetectorRef; constructor(_ref: ChangeDetectorRef) { this._ref = _ref; } - onDestroy(): void { + ngOnDestroy(): void { if (isPresent(this._subscription)) { this._dispose(); } diff --git a/modules/angular2/src/core/change_detection.ts b/modules/angular2/src/core/change_detection.ts index 7d14196b57..6c732c33ea 100644 --- a/modules/angular2/src/core/change_detection.ts +++ b/modules/angular2/src/core/change_detection.ts @@ -15,7 +15,6 @@ export { WrappedValue, SimpleChange, PipeTransform, - PipeOnDestroy, IterableDiffers, IterableDiffer, IterableDifferFactory, diff --git a/modules/angular2/src/core/change_detection/change_detection.ts b/modules/angular2/src/core/change_detection/change_detection.ts index 25284eb53d..2b8954243d 100644 --- a/modules/angular2/src/core/change_detection/change_detection.ts +++ b/modules/angular2/src/core/change_detection/change_detection.ts @@ -39,7 +39,7 @@ export {DynamicChangeDetector} from './dynamic_change_detector'; export {ChangeDetectorRef} from './change_detector_ref'; export {IterableDiffers, IterableDiffer, IterableDifferFactory} from './differs/iterable_differs'; export {KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory} from './differs/keyvalue_differs'; -export {PipeTransform, PipeOnDestroy} from './pipe_transform'; +export {PipeTransform} from './pipe_transform'; export {WrappedValue, SimpleChange} from './change_detection_util'; /** diff --git a/modules/angular2/src/core/change_detection/change_detection_util.ts b/modules/angular2/src/core/change_detection/change_detection_util.ts index f80750b2f3..8d65100077 100644 --- a/modules/angular2/src/core/change_detection/change_detection_util.ts +++ b/modules/angular2/src/core/change_detection/change_detection_util.ts @@ -195,7 +195,7 @@ export class ChangeDetectionUtil { static callPipeOnDestroy(selectedPipe: SelectedPipe): void { if (implementsOnDestroy(selectedPipe.pipe)) { - (selectedPipe.pipe).onDestroy(); + (selectedPipe.pipe).ngOnDestroy(); } } diff --git a/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.dart b/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.dart index 3951dc4f20..1aa45742b5 100644 --- a/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.dart +++ b/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.dart @@ -1,5 +1,5 @@ library angular2.core.compiler.pipe_lifecycle_reflector; -import 'package:angular2/src/core/change_detection/pipe_transform.dart'; +import 'package:angular2/src/core/linker/interfaces.dart'; -bool implementsOnDestroy(Object pipe) => pipe is PipeOnDestroy; +bool implementsOnDestroy(Object pipe) => pipe is OnDestroy; diff --git a/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.ts b/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.ts index 6f6863cd3b..21ea94379b 100644 --- a/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.ts +++ b/modules/angular2/src/core/change_detection/pipe_lifecycle_reflector.ts @@ -1,3 +1,3 @@ export function implementsOnDestroy(pipe: any): boolean { - return pipe.constructor.prototype.onDestroy; + return pipe.constructor.prototype.ngOnDestroy; } diff --git a/modules/angular2/src/core/change_detection/pipe_transform.ts b/modules/angular2/src/core/change_detection/pipe_transform.ts index 1e6579e21b..82d31b2646 100644 --- a/modules/angular2/src/core/change_detection/pipe_transform.ts +++ b/modules/angular2/src/core/change_detection/pipe_transform.ts @@ -31,55 +31,3 @@ * */ export interface PipeTransform { transform(value: any, args: any[]): any; } - -/** - * To create a stateful Pipe, you should implement this interface and set the `pure` - * parameter to `false` in the {@link PipeMetadata}. - * - * A stateful pipe may produce different output, given the same input. It is - * likely that a stateful pipe may contain state that should be cleaned up when - * a binding is destroyed. For example, a subscription to a stream of data may need to - * be disposed, or an interval may need to be cleared. - * - * ### Example ([live demo](http://plnkr.co/edit/i8pm5brO4sPaLxBx56MR?p=preview)) - * - * In this example, a pipe is created to countdown its input value, updating it every - * 50ms. Because it maintains an internal interval, it automatically clears - * the interval when the binding is destroyed or the countdown completes. - * - * ``` - * import {Pipe, PipeTransform} from 'angular2/angular2' - * @Pipe({name: 'countdown', pure: false}) - * class CountDown implements PipeTransform, PipeOnDestroy { - * remainingTime:Number; - * interval:SetInterval; - * onDestroy() { - * if (this.interval) { - * clearInterval(this.interval); - * } - * } - * transform(value: any, args: any[] = []) { - * if (!parseInt(value, 10)) return null; - * if (typeof this.remainingTime !== 'number') { - * this.remainingTime = parseInt(value, 10); - * } - * if (!this.interval) { - * this.interval = setInterval(() => { - * this.remainingTime-=50; - * if (this.remainingTime <= 0) { - * this.remainingTime = 0; - * clearInterval(this.interval); - * delete this.interval; - * } - * }, 50); - * } - * return this.remainingTime; - * } - * } - * ``` - * - * Invoking `{{ 10000 | countdown }}` would cause the value to be decremented by 50, - * every 50ms, until it reaches 0. - * - */ -export interface PipeOnDestroy { onDestroy(): void; } diff --git a/modules/angular2/src/core/linker/interfaces.ts b/modules/angular2/src/core/linker/interfaces.ts index 71a7030995..4ad40f4244 100644 --- a/modules/angular2/src/core/linker/interfaces.ts +++ b/modules/angular2/src/core/linker/interfaces.ts @@ -226,6 +226,56 @@ export interface DoCheck { ngDoCheck(); } * * bootstrap(App).catch(err => console.error(err)); * ``` + * + * + * To create a stateful Pipe, you should implement this interface and set the `pure` + * parameter to `false` in the {@link PipeMetadata}. + * + * A stateful pipe may produce different output, given the same input. It is + * likely that a stateful pipe may contain state that should be cleaned up when + * a binding is destroyed. For example, a subscription to a stream of data may need to + * be disposed, or an interval may need to be cleared. + * + * ### Example ([live demo](http://plnkr.co/edit/i8pm5brO4sPaLxBx56MR?p=preview)) + * + * In this example, a pipe is created to countdown its input value, updating it every + * 50ms. Because it maintains an internal interval, it automatically clears + * the interval when the binding is destroyed or the countdown completes. + * + * ``` + * import {OnDestroy, Pipe, PipeTransform} from 'angular2/angular2' + * @Pipe({name: 'countdown', pure: false}) + * class CountDown implements PipeTransform, OnDestroy { + * remainingTime:Number; + * interval:SetInterval; + * ngOnDestroy() { + * if (this.interval) { + * clearInterval(this.interval); + * } + * } + * transform(value: any, args: any[] = []) { + * if (!parseInt(value, 10)) return null; + * if (typeof this.remainingTime !== 'number') { + * this.remainingTime = parseInt(value, 10); + * } + * if (!this.interval) { + * this.interval = setInterval(() => { + * this.remainingTime-=50; + * if (this.remainingTime <= 0) { + * this.remainingTime = 0; + * clearInterval(this.interval); + * delete this.interval; + * } + * }, 50); + * } + * return this.remainingTime; + * } + * } + * ``` + * + * Invoking `{{ 10000 | countdown }}` would cause the value to be decremented by 50, + * every 50ms, until it reaches 0. + * */ export interface OnDestroy { ngOnDestroy(); } diff --git a/modules/angular2/test/common/pipes/async_pipe_spec.ts b/modules/angular2/test/common/pipes/async_pipe_spec.ts index 1268547749..d962e95a17 100644 --- a/modules/angular2/test/common/pipes/async_pipe_spec.ts +++ b/modules/angular2/test/common/pipes/async_pipe_spec.ts @@ -96,13 +96,13 @@ export function main() { })); }); - describe("onDestroy", () => { + describe("ngOnDestroy", () => { it("should do nothing when no subscription", - () => { expect(() => pipe.onDestroy()).not.toThrow(); }); + () => { expect(() => pipe.ngOnDestroy()).not.toThrow(); }); it("should dispose of the existing subscription", inject([AsyncTestCompleter], (async) => { pipe.transform(emitter); - pipe.onDestroy(); + pipe.ngOnDestroy(); ObservableWrapper.callEmit(emitter, message); @@ -182,9 +182,9 @@ export function main() { }, timer) })); - describe("onDestroy", () => { + describe("ngOnDestroy", () => { it("should do nothing when no source", - () => { expect(() => pipe.onDestroy()).not.toThrow(); }); + () => { expect(() => pipe.ngOnDestroy()).not.toThrow(); }); it("should dispose of the existing source", inject([AsyncTestCompleter], (async) => { pipe.transform(completer.promise); @@ -194,7 +194,7 @@ export function main() { TimerWrapper.setTimeout(() => { expect(pipe.transform(completer.promise)).toEqual(new WrappedValue(message)); - pipe.onDestroy(); + pipe.ngOnDestroy(); expect(pipe.transform(completer.promise)).toBe(null); async.done(); }, timer); diff --git a/modules/angular2/test/common/pipes/pipes_spec.ts b/modules/angular2/test/common/pipes/pipes_spec.ts index 94cd6572be..6a40613158 100644 --- a/modules/angular2/test/common/pipes/pipes_spec.ts +++ b/modules/angular2/test/common/pipes/pipes_spec.ts @@ -10,20 +10,20 @@ import { afterEach } from 'angular2/testing_internal'; -import {Injector, Inject, provide, Pipe, PipeTransform} from 'angular2/core'; +import {Injector, Inject, provide, Pipe, PipeTransform, OnDestroy} from 'angular2/core'; import {ProtoPipes, Pipes} from 'angular2/src/core/pipes/pipes'; import {PipeProvider} from 'angular2/src/core/pipes/pipe_provider'; -class PipeA implements PipeTransform { +class PipeA implements PipeTransform, OnDestroy { transform(a, b) {} - onDestroy() {} + ngOnDestroy() {} } -class PipeB implements PipeTransform { +class PipeB implements PipeTransform, OnDestroy { dep; constructor(@Inject("dep") dep: any) { this.dep = dep; } transform(a, b) {} - onDestroy() {} + ngOnDestroy() {} } export function main() { diff --git a/modules/angular2/test/core/change_detection/change_detector_spec.ts b/modules/angular2/test/core/change_detection/change_detector_spec.ts index b45ec9eb5b..5128cfd2bf 100644 --- a/modules/angular2/test/core/change_detection/change_detector_spec.ts +++ b/modules/angular2/test/core/change_detection/change_detector_spec.ts @@ -35,7 +35,6 @@ import { DirectiveRecord, DirectiveIndex, PipeTransform, - PipeOnDestroy, ChangeDetectionStrategy, WrappedValue, DynamicProtoChangeDetector, @@ -48,6 +47,7 @@ import { import {SelectedPipe, Pipes} from 'angular2/src/core/change_detection/pipes'; import {JitProtoChangeDetector} from 'angular2/src/core/change_detection/jit_proto_change_detector'; +import {OnDestroy} from 'angular2/src/core/linker/interfaces'; import {getDefinition} from './change_detector_config'; import {createObservableModel} from './change_detector_spec_util'; @@ -1228,7 +1228,7 @@ export function main() { expect(cd.hydrated()).toBe(true); }); - it('should destroy all active pipes implementing onDestroy during dehyration', () => { + it('should destroy all active pipes implementing ngOnDestroy during dehyration', () => { var pipe = new PipeWithOnDestroy(); var registry = new FakePipes('pipe', () => pipe); var cd = _createChangeDetector('name | pipe', new Person('bob'), registry).changeDetector; @@ -1239,7 +1239,7 @@ export function main() { expect(pipe.destroyCalled).toBe(true); }); - it('should not call onDestroy all pipes that do not implement onDestroy', () => { + it('should not call ngOnDestroy all pipes that do not implement ngOnDestroy', () => { var pipe = new CountingPipe(); var registry = new FakePipes('pipe', () => pipe); var cd = _createChangeDetector('name | pipe', new Person('bob'), registry).changeDetector; @@ -1365,9 +1365,9 @@ class CountingPipe implements PipeTransform { transform(value, args = null) { return `${value} state:${this.state ++}`; } } -class PipeWithOnDestroy implements PipeTransform, PipeOnDestroy { +class PipeWithOnDestroy implements PipeTransform, OnDestroy { destroyCalled: boolean = false; - onDestroy() { this.destroyCalled = true; } + ngOnDestroy() { this.destroyCalled = true; } transform(value, args = null) { return null; } } diff --git a/modules/angular2/test/core/linker/integration_spec.ts b/modules/angular2/test/core/linker/integration_spec.ts index 13d53f3dfb..c6313b3d1f 100644 --- a/modules/angular2/test/core/linker/integration_spec.ts +++ b/modules/angular2/test/core/linker/integration_spec.ts @@ -54,7 +54,8 @@ import { Inject, Host, SkipSelf, - SkipSelfMetadata + SkipSelfMetadata, + OnDestroy } from 'angular2/core'; import {NgIf, NgFor} from 'angular2/common'; @@ -1999,8 +2000,8 @@ class SomeViewport { } @Pipe({name: 'double'}) -class DoublePipe implements PipeTransform { - onDestroy() {} +class DoublePipe implements PipeTransform, OnDestroy { + ngOnDestroy() {} transform(value, args = null) { return `${value}${value}`; } } diff --git a/modules/angular2/test/public_api_spec.ts b/modules/angular2/test/public_api_spec.ts index 62ec7041cd..199741fd8b 100644 --- a/modules/angular2/test/public_api_spec.ts +++ b/modules/angular2/test/public_api_spec.ts @@ -108,7 +108,7 @@ var NG_ALL = [ 'ApplicationRef.tick()', */ 'AsyncPipe', - 'AsyncPipe.onDestroy()', + 'AsyncPipe.ngOnDestroy()', 'AsyncPipe.transform()', 'Attribute', 'Attribute.attributeName', @@ -1425,7 +1425,6 @@ var NG_ALL = [ 'OnChanges:dart', 'OnDestroy:dart', 'OnInit:dart', - 'PipeOnDestroy:dart', 'PipeTransform:dart', 'reflector', 'RenderBeginCmd:dart',