1- import { isPresent , isBlank , BaseException } from 'angular2/src/facade/lang' ;
1+ import { isPresent , isBlank , BaseException , StringWrapper } from 'angular2/src/facade/lang' ;
22import { List , ListWrapper } from 'angular2/src/facade/collection' ;
33import { ChangeDetectionUtil } from './change_detection_util' ;
44import { ChangeDetectorRef } from './change_detector_ref' ;
@@ -13,8 +13,9 @@ import {
1313import { ProtoRecord } from './proto_record' ;
1414import { BindingRecord } from './binding_record' ;
1515import { Locals } from './parser/locals' ;
16- import { CHECK_ALWAYS , CHECK_ONCE , CHECKED , DETACHED , ON_PUSH } from './constants' ;
16+ import { CHECK_ALWAYS , CHECK_ONCE , CHECKED , DETACHED } from './constants' ;
1717import { wtfCreateScope , wtfLeave , WtfScopeFn } from '../profile/profile' ;
18+ import { isObservable } from './observable_facade' ;
1819
1920var _scope_check : WtfScopeFn = wtfCreateScope ( `ChangeDetector#check(ascii id, bool throwOnChange)` ) ;
2021
@@ -42,6 +43,10 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
4243 firstProtoInCurrentBinding : number ;
4344 protos : List < ProtoRecord > ;
4445
46+ // This is an experimental feature. Works only in Dart.
47+ subscriptions : any [ ] ;
48+ streams : any [ ] ;
49+
4550 constructor ( public id : string , dispatcher : ChangeDispatcher , protos : List < ProtoRecord > ,
4651 directiveRecords : List < DirectiveRecord > , public modeOnHydrate : string ) {
4752 this . ref = new ChangeDetectorRef ( this ) ;
@@ -79,13 +84,14 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
7984 checkNoChanges ( ) : void { throw new BaseException ( "Not implemented" ) ; }
8085
8186 runDetectChanges ( throwOnChange : boolean ) : void {
82- if ( this . mode === DETACHED || this . mode === CHECKED ) return ;
87+ if ( StringWrapper . equals ( this . mode , DETACHED ) || StringWrapper . equals ( this . mode , CHECKED ) )
88+ return ;
8389 var s = _scope_check ( this . id , throwOnChange ) ;
8490 this . detectChangesInRecords ( throwOnChange ) ;
8591 this . _detectChangesInLightDomChildren ( throwOnChange ) ;
8692 if ( throwOnChange === false ) this . callOnAllChangesDone ( ) ;
8793 this . _detectChangesInShadowDomChildren ( throwOnChange ) ;
88- if ( this . mode === CHECK_ONCE ) this . mode = CHECKED ;
94+ if ( StringWrapper . equals ( this . mode , CHECK_ONCE ) ) this . mode = CHECKED ;
8995 wtfLeave ( s ) ;
9096 }
9197
@@ -132,6 +138,10 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
132138 // implementation of `dehydrateDirectives`.
133139 dehydrate ( ) : void {
134140 this . dehydrateDirectives ( true ) ;
141+
142+ // This is an experimental feature. Works only in Dart.
143+ this . unsubsribeFromObservables ( ) ;
144+
135145 this . context = null ;
136146 this . locals = null ;
137147 this . pipes = null ;
@@ -163,12 +173,43 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
163173
164174 markPathToRootAsCheckOnce ( ) : void {
165175 var c : ChangeDetector = this ;
166- while ( isPresent ( c ) && c . mode != DETACHED ) {
167- if ( c . mode === CHECKED ) c . mode = CHECK_ONCE ;
176+ while ( isPresent ( c ) && ! StringWrapper . equals ( c . mode , DETACHED ) ) {
177+ if ( StringWrapper . equals ( c . mode , CHECKED ) ) c . mode = CHECK_ONCE ;
168178 c = c . parent ;
169179 }
170180 }
171181
182+ private unsubsribeFromObservables ( ) : void {
183+ if ( isPresent ( this . subscriptions ) ) {
184+ for ( var i = 0 ; i < this . subscriptions . length ; ++ i ) {
185+ var s = this . subscriptions [ i ] ;
186+ if ( isPresent ( this . subscriptions [ i ] ) ) {
187+ s . cancel ( ) ;
188+ this . subscriptions [ i ] = null ;
189+ }
190+ }
191+ }
192+ }
193+
194+ // This is an experimental feature. Works only in Dart.
195+ protected observe ( value : any , index : number ) : any {
196+ if ( isObservable ( value ) ) {
197+ if ( isBlank ( this . subscriptions ) ) {
198+ this . subscriptions = ListWrapper . createFixedSize ( this . protos . length + 1 ) ;
199+ this . streams = ListWrapper . createFixedSize ( this . protos . length + 1 ) ;
200+ }
201+ if ( isBlank ( this . subscriptions [ index ] ) ) {
202+ this . streams [ index ] = value . changes ;
203+ this . subscriptions [ index ] = value . changes . listen ( ( _ ) => this . ref . requestCheck ( ) ) ;
204+ } else if ( this . streams [ index ] !== value . changes ) {
205+ this . subscriptions [ index ] . cancel ( ) ;
206+ this . streams [ index ] = value . changes ;
207+ this . subscriptions [ index ] = value . changes . listen ( ( _ ) => this . ref . requestCheck ( ) ) ;
208+ }
209+ }
210+ return value ;
211+ }
212+
172213 protected notifyDispatcher ( value : any ) : void {
173214 this . dispatcher . notifyOnBinding ( this . _currentBinding ( ) , value ) ;
174215 }
0 commit comments