Skip to content

Commit 106a28b

Browse files
committed
feat(refactor): replaced ObservablePipe and PromisePipe with AsyncPipe
1 parent bd49897 commit 106a28b

File tree

9 files changed

+363
-439
lines changed

9 files changed

+363
-439
lines changed

modules/angular2/pipes.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
* This module provides advanced support for extending change detection.
55
*/
66

7-
export {PromisePipe} from './src/change_detection/pipes/promise_pipe';
87
export {UpperCasePipe} from './src/change_detection/pipes/uppercase_pipe';
98
export {LowerCasePipe} from './src/change_detection/pipes/lowercase_pipe';
10-
export {ObservablePipe} from './src/change_detection/pipes/observable_pipe';
9+
export {AsyncPipe} from './src/change_detection/pipes/async_pipe';
1110
export {JsonPipe} from './src/change_detection/pipes/json_pipe';
1211
export {DatePipe} from './src/change_detection/pipes/date_pipe';
1312
export {DecimalPipe, PercentPipe, CurrencyPipe} from './src/change_detection/pipes/number_pipe';

modules/angular2/src/change_detection/change_detection.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs
77
import {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
88
import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs';
99
import {DefaultKeyValueDifferFactory} from './differs/default_keyvalue_differ';
10-
import {ObservablePipeFactory} from './pipes/observable_pipe';
11-
import {PromisePipeFactory} from './pipes/promise_pipe';
10+
import {AsyncPipeFactory} from './pipes/async_pipe';
1211
import {UpperCasePipe} from './pipes/uppercase_pipe';
1312
import {LowerCasePipe} from './pipes/lowercase_pipe';
1413
import {JsonPipe} from './pipes/json_pipe';
@@ -75,11 +74,8 @@ export const iterableDiff: IterableDifferFactory[] =
7574
/**
7675
* Async binding to such types as Observable.
7776
*/
78-
export const async: List<PipeFactory> = CONST_EXPR([
79-
CONST_EXPR(new ObservablePipeFactory()),
80-
CONST_EXPR(new PromisePipeFactory()),
81-
CONST_EXPR(new NullPipeFactory())
82-
]);
77+
export const async: List<PipeFactory> =
78+
CONST_EXPR([CONST_EXPR(new AsyncPipeFactory()), CONST_EXPR(new NullPipeFactory())]);
8379

8480
/**
8581
* Uppercase text transform.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import {isBlank, isPresent, isPromise, CONST, BaseException} from 'angular2/src/facade/lang';
2+
import {Observable, Promise, ObservableWrapper} from 'angular2/src/facade/async';
3+
import {Pipe, WrappedValue, PipeFactory} from './pipe';
4+
import {ChangeDetectorRef} from '../change_detector_ref';
5+
6+
7+
class ObservableStrategy {
8+
createSubscription(async: any, updateLatestValue: any): any {
9+
return ObservableWrapper.subscribe(async, updateLatestValue, e => { throw e; });
10+
}
11+
12+
dispose(subscription: any): void { ObservableWrapper.dispose(subscription); }
13+
14+
onDestroy(subscription: any): void { ObservableWrapper.dispose(subscription); }
15+
}
16+
17+
class PromiseStrategy {
18+
createSubscription(async: any, updateLatestValue: any): any {
19+
return async.then(updateLatestValue);
20+
}
21+
22+
dispose(subscription: any): void {}
23+
24+
onDestroy(subscription: any): void {}
25+
}
26+
27+
var _promiseStrategy = new PromiseStrategy();
28+
var _observableStrategy = new ObservableStrategy();
29+
30+
31+
/**
32+
* Implements async bindings to Observable and Promise.
33+
*
34+
* # Example
35+
*
36+
* In this example we bind the description observable to the DOM. The async pipe will convert an
37+
*observable to the
38+
* latest value it emitted. It will also request a change detection check when a new value is
39+
*emitted.
40+
*
41+
* ```
42+
* @Component({
43+
* selector: "task-cmp",
44+
* changeDetection: ON_PUSH
45+
* })
46+
* @View({
47+
* template: "Task Description {{ description | async }}"
48+
* })
49+
* class Task {
50+
* description:Observable<string>;
51+
* }
52+
*
53+
* ```
54+
*/
55+
export class AsyncPipe implements Pipe {
56+
_latestValue: Object = null;
57+
_latestReturnedValue: Object = null;
58+
59+
_subscription: Object = null;
60+
_obj: Observable | Promise<any> = null;
61+
private _strategy: any = null;
62+
63+
constructor(public _ref: ChangeDetectorRef) {}
64+
65+
supports(obj: any): boolean { return true; }
66+
67+
onDestroy(): void {
68+
if (isPresent(this._subscription)) {
69+
this._dispose();
70+
}
71+
}
72+
73+
transform(obj: Observable | Promise<any>, args?: any[]): any {
74+
if (isBlank(this._obj)) {
75+
if (isPresent(obj)) {
76+
this._subscribe(obj);
77+
}
78+
return null;
79+
}
80+
81+
if (obj !== this._obj) {
82+
this._dispose();
83+
return this.transform(obj);
84+
}
85+
86+
if (this._latestValue === this._latestReturnedValue) {
87+
return this._latestReturnedValue;
88+
} else {
89+
this._latestReturnedValue = this._latestValue;
90+
return WrappedValue.wrap(this._latestValue);
91+
}
92+
}
93+
94+
_subscribe(obj: Observable | Promise<any>): void {
95+
this._obj = obj;
96+
this._strategy = this._selectStrategy(obj);
97+
this._subscription =
98+
this._strategy.createSubscription(obj, value => this._updateLatestValue(obj, value));
99+
}
100+
101+
_selectStrategy(obj: Observable | Promise<any>) {
102+
if (isPromise(obj)) {
103+
return _promiseStrategy;
104+
} else if (ObservableWrapper.isObservable(obj)) {
105+
return _observableStrategy;
106+
} else {
107+
throw new BaseException(`Async pipe does not support object '${obj}'`);
108+
}
109+
}
110+
111+
_dispose(): void {
112+
this._strategy.dispose(this._subscription);
113+
this._latestValue = null;
114+
this._latestReturnedValue = null;
115+
this._subscription = null;
116+
this._obj = null;
117+
}
118+
119+
_updateLatestValue(async: any, value: Object) {
120+
if (async === this._obj) {
121+
this._latestValue = value;
122+
this._ref.requestCheck();
123+
}
124+
}
125+
}
126+
127+
/**
128+
* Provides a factory for [AsyncPipe].
129+
*/
130+
@CONST()
131+
export class AsyncPipeFactory implements PipeFactory {
132+
supports(obj: any): boolean { return true; }
133+
create(cdRef: ChangeDetectorRef): Pipe { return new AsyncPipe(cdRef); }
134+
}

modules/angular2/src/change_detection/pipes/observable_pipe.ts

Lines changed: 0 additions & 94 deletions
This file was deleted.

modules/angular2/src/change_detection/pipes/promise_pipe.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

modules/angular2/src/test_lib/spies.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
ChangeDetector,
3+
ChangeDetectorRef,
34
ProtoChangeDetector,
45
DynamicChangeDetector
56
} from 'angular2/src/change_detection/change_detection';
@@ -26,3 +27,7 @@ export class SpyPipeFactory extends SpyObject {}
2627
export class SpyDependencyProvider extends SpyObject {}
2728

2829
export class SpyIterableDifferFactory extends SpyObject {}
30+
31+
export class SpyChangeDetectorRef extends SpyObject {
32+
constructor() { super(ChangeDetectorRef); }
33+
}

0 commit comments

Comments
 (0)