6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
9
+ import { coerceBooleanProperty , coerceNumberProperty } from '@angular/cdk/coercion' ;
10
10
import {
11
11
AfterContentInit ,
12
12
Directive ,
@@ -16,12 +16,10 @@ import {
16
16
Input ,
17
17
NgModule ,
18
18
NgZone ,
19
- OnChanges ,
20
19
OnDestroy ,
21
20
Output ,
22
- SimpleChanges ,
23
21
} from '@angular/core' ;
24
- import { Subject } from 'rxjs' ;
22
+ import { Observable , Subject } from 'rxjs' ;
25
23
import { debounceTime } from 'rxjs/operators' ;
26
24
27
25
/**
@@ -35,6 +33,56 @@ export class MutationObserverFactory {
35
33
}
36
34
}
37
35
36
+
37
+ /** A factory that creates ContentObservers. */
38
+ @Injectable ( { providedIn : 'root' } )
39
+ export class ContentObserverFactory {
40
+ constructor ( private _mutationObserverFactory : MutationObserverFactory , private _ngZone : NgZone ) { }
41
+
42
+ create ( element : Element , debounce ?: number ) {
43
+ const changes = new Subject < MutationRecord [ ] > ( ) ;
44
+ const observer = this . _ngZone . runOutsideAngular (
45
+ ( ) => this . _mutationObserverFactory . create ( ( mutations ) => changes . next ( mutations ) ) ) ;
46
+ return new ContentObserver ( element , observer , changes , debounce ) ;
47
+ }
48
+ }
49
+
50
+
51
+ /** A class that observes an element for content changes. */
52
+ export class ContentObserver {
53
+ changes : Observable < MutationRecord [ ] > ;
54
+
55
+ constructor ( private _element : Element , private _mutationObserver : MutationObserver | null ,
56
+ private _rawChanges : Subject < MutationRecord [ ] > , debounce : number = 0 ) {
57
+ this . changes = debounce ?
58
+ this . _rawChanges . pipe ( debounceTime ( debounce ) ) : this . _rawChanges . asObservable ( ) ;
59
+ }
60
+
61
+ start ( ) : ContentObserver {
62
+ if ( this . _mutationObserver ) {
63
+ this . _mutationObserver . observe ( this . _element , {
64
+ characterData : true ,
65
+ childList : true ,
66
+ subtree : true
67
+ } ) ;
68
+ }
69
+ return this ;
70
+ }
71
+
72
+ pause ( ) {
73
+ if ( this . _mutationObserver ) {
74
+ this . _mutationObserver . disconnect ( ) ;
75
+ }
76
+ }
77
+
78
+ stop ( ) {
79
+ this . pause ( ) ;
80
+ this . _rawChanges . complete ( ) ;
81
+ this . _mutationObserver = null ;
82
+ }
83
+ }
84
+
85
+
38
86
/**
39
87
* Directive that triggers a callback whenever the content of
40
88
* its associated element has changed.
@@ -43,10 +91,7 @@ export class MutationObserverFactory {
43
91
selector : '[cdkObserveContent]' ,
44
92
exportAs : 'cdkObserveContent' ,
45
93
} )
46
- export class CdkObserveContent implements AfterContentInit , OnChanges , OnDestroy {
47
- private _observer : MutationObserver | null ;
48
- private _disabled = false ;
49
-
94
+ export class CdkObserveContent implements AfterContentInit , OnDestroy {
50
95
/** Event emitted for each change in the element's content. */
51
96
@Output ( 'cdkObserveContent' ) event = new EventEmitter < MutationRecord [ ] > ( ) ;
52
97
@@ -58,65 +103,42 @@ export class CdkObserveContent implements AfterContentInit, OnChanges, OnDestroy
58
103
get disabled ( ) { return this . _disabled ; }
59
104
set disabled ( value : any ) {
60
105
this . _disabled = coerceBooleanProperty ( value ) ;
106
+ if ( this . _observer ) {
107
+ if ( this . _disabled ) {
108
+ this . _observer . pause ( ) ;
109
+ } else {
110
+ this . _observer . start ( ) ;
111
+ }
112
+ }
61
113
}
62
-
63
- /** Used for debouncing the emitted values to the observeContent event. */
64
- private _debouncer = new Subject < MutationRecord [ ] > ( ) ;
114
+ private _disabled = false ;
65
115
66
116
/** Debounce interval for emitting the changes. */
67
- @Input ( ) debounce : number ;
117
+ @Input ( )
118
+ get debounce ( ) : number { return this . _debounce ; }
119
+ set debounce ( value : number ) {
120
+ this . _debounce = coerceNumberProperty ( value ) ;
121
+ }
122
+ private _debounce : number ;
68
123
69
- constructor (
70
- private _mutationObserverFactory : MutationObserverFactory ,
71
- private _elementRef : ElementRef ,
72
- private _ngZone : NgZone ) { }
124
+ private _observer : ContentObserver ;
73
125
74
- ngAfterContentInit ( ) {
75
- if ( this . debounce > 0 ) {
76
- this . _ngZone . runOutsideAngular ( ( ) => {
77
- this . _debouncer . pipe ( debounceTime ( this . debounce ) )
78
- . subscribe ( ( mutations : MutationRecord [ ] ) => this . event . emit ( mutations ) ) ;
79
- } ) ;
80
- } else {
81
- this . _debouncer . subscribe ( mutations => this . event . emit ( mutations ) ) ;
82
- }
126
+ constructor ( private _contentObserverFactory : ContentObserverFactory ,
127
+ private _elementRef : ElementRef , private _ngZone : NgZone ) { }
83
128
84
- this . _observer = this . _ngZone . runOutsideAngular ( ( ) => {
85
- return this . _mutationObserverFactory . create ( ( mutations : MutationRecord [ ] ) => {
86
- this . _debouncer . next ( mutations ) ;
87
- } ) ;
88
- } ) ;
129
+ ngAfterContentInit ( ) {
130
+ this . _observer =
131
+ this . _contentObserverFactory . create ( this . _elementRef . nativeElement , this . debounce ) ;
132
+ this . _ngZone . run (
133
+ ( ) => this . _observer . changes . subscribe ( mutations => this . event . next ( mutations ) ) ) ;
89
134
90
135
if ( ! this . disabled ) {
91
- this . _enable ( ) ;
92
- }
93
- }
94
-
95
- ngOnChanges ( changes : SimpleChanges ) {
96
- if ( changes [ 'disabled' ] ) {
97
- changes [ 'disabled' ] . currentValue ? this . _disable ( ) : this . _enable ( ) ;
136
+ this . _observer . start ( ) ;
98
137
}
99
138
}
100
139
101
140
ngOnDestroy ( ) {
102
- this . _disable ( ) ;
103
- this . _debouncer . complete ( ) ;
104
- }
105
-
106
- private _disable ( ) {
107
- if ( this . _observer ) {
108
- this . _observer . disconnect ( ) ;
109
- }
110
- }
111
-
112
- private _enable ( ) {
113
- if ( this . _observer ) {
114
- this . _observer . observe ( this . _elementRef . nativeElement , {
115
- characterData : true ,
116
- childList : true ,
117
- subtree : true
118
- } ) ;
119
- }
141
+ this . _observer . stop ( ) ;
120
142
}
121
143
}
122
144
0 commit comments