Skip to content

Commit f34cf23

Browse files
author
vakrilov
committed
Manually trigger change detection onItemLoading for current item only
1 parent 2b36449 commit f34cf23

File tree

1 file changed

+52
-22
lines changed

1 file changed

+52
-22
lines changed

nativescript-angular/directives/list-view-comp.ts

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
Component,
33
DoCheck,
4+
OnDestroy,
45
ElementRef,
56
ViewContainerRef,
67
TemplateRef,
@@ -14,7 +15,7 @@ import {
1415
ViewChild,
1516
Output,
1617
NgZone,
17-
ChangeDetectionStrategy} from '@angular/core';
18+
ChangeDetectionStrategy } from '@angular/core';
1819
import {isBlank} from '@angular/core/src/facade/lang';
1920
import {isListLikeIterable} from '@angular/core/src/facade/collection';
2021
import {Observable as RxObservable} from 'rxjs'
@@ -23,7 +24,12 @@ import {View} from 'ui/core/view';
2324
import {NgView} from '../view-util';
2425
import {ObservableArray} from 'data/observable-array';
2526
import {LayoutBase} from 'ui/layouts/layout-base';
27+
<<<<<<< 2b36449d70d559d1fda6cdf4d271246b5fe0ecd2
2628
import {rendererLog, rendererError} from "../trace";
29+
=======
30+
import 'rxjs/add/operator/debounceTime';
31+
32+
>>>>>>> Manually trigger change detection onItemLoading for current item only
2733
const NG_VIEW = "_ngViewRef";
2834

2935
export class ListItemContext {
@@ -52,7 +58,7 @@ export interface SetupItemViewArgs {
5258
inputs: ['items'],
5359
changeDetection: ChangeDetectionStrategy.OnPush
5460
})
55-
export class ListViewComponent {
61+
export class ListViewComponent implements DoCheck, OnDestroy {
5662
public get nativeElement(): ListView {
5763
return this.listView;
5864
}
@@ -76,20 +82,24 @@ export class ListViewComponent {
7682
if (needDiffer && !this._differ && isListLikeIterable(value)) {
7783
this._differ = this._iterableDiffers.find(this._items).create(this._cdr, (index, item) => { return item; });
7884
}
85+
86+
// this._cdr.detach();
7987
this.listView.items = this._items;
8088
}
8189

82-
private timerId: number;
83-
private doCheckDelay = 5;
84-
8590
constructor(private _elementRef: ElementRef,
8691
private _iterableDiffers: IterableDiffers,
8792
private _cdr: ChangeDetectorRef,
8893
private _zone: NgZone) {
8994
this.listView = _elementRef.nativeElement;
95+
96+
this.listView.on("itemLoading", this.onItemLoading, this);
97+
}
98+
99+
ngOnDestroy() {
100+
this.listView.off("itemLoading", this.onItemLoading, this);
90101
}
91102

92-
@HostListener("itemLoading", ['$event'])
93103
public onItemLoading(args) {
94104
if (!this.itemTemplate) {
95105
return;
@@ -101,20 +111,23 @@ export class ListViewComponent {
101111
let viewRef: EmbeddedViewRef<ListItemContext>;
102112

103113
if (args.view) {
104-
rendererLog("ListView.onItemLoading: " + index + " - Reusing existing view");
114+
log("ListView.onItemLoading: " + index + " - Reusing existing view");
115+
105116
viewRef = args.view[NG_VIEW];
106117
// getting angular view from original element (in cases when ProxyViewContainer is used NativeScript internally wraps it in a StackLayout)
107118
if (!viewRef) {
108119
viewRef = (args.view._subViews && args.view._subViews.length > 0) ? args.view._subViews[0][NG_VIEW] : undefined;
109120
}
110121
}
111122
else {
112-
rendererLog("ListView.onItemLoading: " + index + " - Creating view from template");
123+
log("ListView.onItemLoading: " + index + " - Creating view from template");
113124
viewRef = this.loader.createEmbeddedView(this.itemTemplate, new ListItemContext(), 0);
114125
args.view = getSingleViewFromViewRef(viewRef);
115126
args.view[NG_VIEW] = viewRef;
116127
}
117128
this.setupViewRef(viewRef, currentItem, index);
129+
130+
this.detectChangesOnChild(viewRef);
118131
}
119132

120133
public setupViewRef(viewRef: EmbeddedViewRef<ListItemContext>, data: any, index: number): void {
@@ -131,25 +144,42 @@ export class ListViewComponent {
131144
this.setupItemView.next({ view: viewRef, data: data, index: index, context: context });
132145
}
133146

147+
private detectChangesOnChild(viewRef: EmbeddedViewRef<ListItemContext>){
148+
// Manually detect changes in view ref
149+
var childCD = <ChangeDetectorRef>(<any>viewRef);
150+
var childView = (<any>viewRef)._view;
151+
152+
log("------------ detectChanges START ----------")
153+
log("CangeDetectionState child before mark " + this.logCD(childView));
154+
childCD.markForCheck();
155+
childCD.detectChanges();
156+
log("CangeDetectionState child after detect " + this.logCD(childView));
157+
log("------------ detectChanges END ----------")
158+
}
159+
160+
private logCD(cdr: any) {
161+
var modes = ["CheckOnce", "Checked", "CheckAlways", "Detached", "OnPush", "Default"];
162+
var states = ["Never", "CheckedBefore", "Error"];
163+
return "Mode: " + modes[parseInt(cdr.cdMode)] + " State: " + states[parseInt(cdr.cdState)];
164+
}
165+
134166
ngDoCheck() {
135-
if (this.timerId) {
136-
clearTimeout(this.timerId);
167+
if (this._differ) {
168+
log("======> ngDoCheck() DIFFER")
169+
var changes = this._differ.diff(this._items);
170+
if (changes) {
171+
log("======> ngDoCheck() REFRESH")
172+
// this._cdr.detach();
173+
this.listView.refresh();
174+
}
137175
}
138-
139-
this._zone.runOutsideAngular(() => {
140-
this.timerId = setTimeout(() => {
141-
clearTimeout(this.timerId);
142-
if (this._differ) {
143-
var changes = this._differ.diff(this._items);
144-
if (changes) {
145-
this.listView.refresh();
146-
}
147-
}
148-
}, this.doCheckDelay);
149-
});
150176
}
151177
}
152178

179+
function log(msg){
180+
// console.log(msg);
181+
}
182+
153183
function getSingleViewFromViewRef(viewRef: EmbeddedViewRef<any>): View {
154184
var getSingleViewRecursive = (nodes: Array<any>, nestLevel: number) => {
155185
var actualNodes = nodes.filter((n) => !!n && n.nodeName !== "#text");

0 commit comments

Comments
 (0)