Skip to content

Commit eb27a01

Browse files
author
vakrilov
committed
Refactor and simplify
1 parent f34cf23 commit eb27a01

File tree

5 files changed

+74
-91
lines changed

5 files changed

+74
-91
lines changed

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

Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ import {View} from 'ui/core/view';
2424
import {NgView} from '../view-util';
2525
import {ObservableArray} from 'data/observable-array';
2626
import {LayoutBase} from 'ui/layouts/layout-base';
27-
<<<<<<< 2b36449d70d559d1fda6cdf4d271246b5fe0ecd2
28-
import {rendererLog, rendererError} from "../trace";
29-
=======
30-
import 'rxjs/add/operator/debounceTime';
27+
import {listViewLog} from "../trace";
3128

32-
>>>>>>> Manually trigger change detection onItemLoading for current item only
3329
const NG_VIEW = "_ngViewRef";
3430

3531
export class ListItemContext {
@@ -111,23 +107,22 @@ export class ListViewComponent implements DoCheck, OnDestroy {
111107
let viewRef: EmbeddedViewRef<ListItemContext>;
112108

113109
if (args.view) {
114-
log("ListView.onItemLoading: " + index + " - Reusing existing view");
115-
110+
listViewLog("onItemLoading: " + index + " - Reusing existing view");
116111
viewRef = args.view[NG_VIEW];
117112
// getting angular view from original element (in cases when ProxyViewContainer is used NativeScript internally wraps it in a StackLayout)
118113
if (!viewRef) {
119114
viewRef = (args.view._subViews && args.view._subViews.length > 0) ? args.view._subViews[0][NG_VIEW] : undefined;
120115
}
121116
}
122117
else {
123-
log("ListView.onItemLoading: " + index + " - Creating view from template");
118+
listViewLog("onItemLoading: " + index + " - Creating view from template");
124119
viewRef = this.loader.createEmbeddedView(this.itemTemplate, new ListItemContext(), 0);
125120
args.view = getSingleViewFromViewRef(viewRef);
126121
args.view[NG_VIEW] = viewRef;
127122
}
128123
this.setupViewRef(viewRef, currentItem, index);
129124

130-
this.detectChangesOnChild(viewRef);
125+
this.detectChangesOnChild(viewRef, index);
131126
}
132127

133128
public setupViewRef(viewRef: EmbeddedViewRef<ListItemContext>, data: any, index: number): void {
@@ -144,65 +139,60 @@ export class ListViewComponent implements DoCheck, OnDestroy {
144139
this.setupItemView.next({ view: viewRef, data: data, index: index, context: context });
145140
}
146141

147-
private detectChangesOnChild(viewRef: EmbeddedViewRef<ListItemContext>){
142+
private detectChangesOnChild(viewRef: EmbeddedViewRef<ListItemContext>, index: number) {
148143
// 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)];
144+
//
145+
const childChangeDetector = <ChangeDetectorRef>(<any>viewRef);
146+
147+
listViewLog("Manually detect changes in child: " + index)
148+
// listViewLog("CangeDetectionState child before mark " + getChangeDetectorState((<any>viewRef)._view));
149+
childChangeDetector.markForCheck();
150+
childChangeDetector.detectChanges();
151+
// listViewLog("CangeDetectionState child after detect " + getChangeDetectorState((<any>viewRef)._view));
164152
}
165153

166154
ngDoCheck() {
167155
if (this._differ) {
168-
log("======> ngDoCheck() DIFFER")
169-
var changes = this._differ.diff(this._items);
156+
listViewLog("ngDoCheck() - execute differ")
157+
const changes = this._differ.diff(this._items);
170158
if (changes) {
171-
log("======> ngDoCheck() REFRESH")
172-
// this._cdr.detach();
159+
listViewLog("ngDoCheck() - refresh")
173160
this.listView.refresh();
174161
}
175162
}
176163
}
177164
}
178165

179-
function log(msg){
180-
// console.log(msg);
181-
}
182166

183-
function getSingleViewFromViewRef(viewRef: EmbeddedViewRef<any>): View {
184-
var getSingleViewRecursive = (nodes: Array<any>, nestLevel: number) => {
185-
var actualNodes = nodes.filter((n) => !!n && n.nodeName !== "#text");
167+
function getSingleViewRecursive(nodes: Array<any>, nestLevel: number) {
168+
const actualNodes = nodes.filter((n) => !!n && n.nodeName !== "#text");
186169

187-
if (actualNodes.length === 0) {
188-
throw new Error("No suitable views found in list template! Nesting level: " + nestLevel);
189-
}
190-
else if (actualNodes.length > 1) {
191-
throw new Error("More than one view found in list template! Nesting level: " + nestLevel);
170+
if (actualNodes.length === 0) {
171+
throw new Error("No suitable views found in list template! Nesting level: " + nestLevel);
172+
}
173+
else if (actualNodes.length > 1) {
174+
throw new Error("More than one view found in list template! Nesting level: " + nestLevel);
175+
}
176+
else {
177+
if (actualNodes[0]) {
178+
let parentLayout = actualNodes[0].parent;
179+
if (parentLayout instanceof LayoutBase) {
180+
parentLayout.removeChild(actualNodes[0]);
181+
}
182+
return actualNodes[0];
192183
}
193184
else {
194-
if (actualNodes[0]) {
195-
let parentLayout = actualNodes[0].parent;
196-
if (parentLayout instanceof LayoutBase) {
197-
parentLayout.removeChild(actualNodes[0]);
198-
}
199-
return actualNodes[0];
200-
}
201-
else {
202-
return getSingleViewRecursive(actualNodes[0].children, nestLevel + 1)
203-
}
185+
return getSingleViewRecursive(actualNodes[0].children, nestLevel + 1)
204186
}
205187
}
188+
}
206189

190+
function getSingleViewFromViewRef(viewRef: EmbeddedViewRef<any>): View {
207191
return getSingleViewRecursive(viewRef.rootNodes, 0);
208192
}
193+
194+
const changeDetectorMode = ["CheckOnce", "Checked", "CheckAlways", "Detached", "OnPush", "Default"];
195+
const changeDetectorStates = ["Never", "CheckedBefore", "Error"];
196+
function getChangeDetectorState(cdr: any) {
197+
return "Mode: " + changeDetectorMode[parseInt(cdr.cdMode)] + " State: " + changeDetectorStates[parseInt(cdr.cdState)];
198+
}

nativescript-angular/trace.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {write, categories, messageType} from "trace";
22

33
export const rendererTraceCategory = "ns-renderer";
44
export const routerTraceCategory = "ns-router";
5+
export const listViewTraceCategory = "ns-list-view";
56

67
export function rendererLog(msg): void {
78
write(msg, rendererTraceCategory);
@@ -18,3 +19,7 @@ export function routerLog(message: string): void {
1819
export function styleError(message: string): void {
1920
write(message, categories.Style, messageType.error);
2021
}
22+
23+
export function listViewLog(message: string): void {
24+
write(message, listViewTraceCategory);
25+
}

ng-sample/app/app.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
// this import should be first in order to load some required settings (like globals and reflect-metadata)
99
import { nativeScriptBootstrap } from "nativescript-angular/application";
1010
import { NS_ROUTER_PROVIDERS } from "nativescript-angular/router";
11-
import { rendererTraceCategory, routerTraceCategory } from "nativescript-angular/trace";
11+
import { rendererTraceCategory, routerTraceCategory, listViewTraceCategory } from "nativescript-angular/trace";
1212

1313
import trace = require("trace");
14-
trace.setCategories(routerTraceCategory);
14+
// trace.setCategories(rendererTraceCategory);
15+
// trace.setCategories(routerTraceCategory);
16+
trace.setCategories(listViewTraceCategory);
1517
trace.enable();
1618

1719
import {RendererTest} from './examples/renderer-test';
@@ -30,7 +32,7 @@ import {LoginTest} from "./examples/navigation/login-test";
3032
//nativeScriptBootstrap(RendererTest);
3133
//nativeScriptBootstrap(TabViewTest);
3234
//nativeScriptBootstrap(Benchmark);
33-
//nativeScriptBootstrap(ListTest);
35+
// nativeScriptBootstrap(ListTest);
3436
// nativeScriptBootstrap(ListTestAsync);
3537
nativeScriptBootstrap(ListTestFilterAsync);
3638
//nativeScriptBootstrap(ImageTest);

ng-sample/app/examples/list/list-test-async.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ import { DataItem, DataService } from "./data.service"
1717
<ListView row="1" [items]="service.items$ | async" (itemTap)="onItemTap($event)" margin="10">
1818
<template let-item="item" let-i="index" let-odd="odd" let-even="even">
1919
<StackLayout [class.odd]="odd" [class.even]="even">
20-
<Label [text]='"index: " + item.name'></Label>
20+
<Label [text]='"name: " + item.name'></Label>
2121
</StackLayout>
2222
</template>
2323
</ListView>
2424
2525
<StackLayout row="1" col="1" margin="10">
2626
<StackLayout *ngFor="let item of (service.items$ | async); let odd = odd; let even = even"
2727
[class.odd]="odd" [class.even]="even" marginBottom="1">
28-
<Label [text]='"index: " + item.name'></Label>
28+
<Label [text]='"name: " + item.name'></Label>
2929
</StackLayout>
3030
</StackLayout>
3131
@@ -57,7 +57,7 @@ export class ListTestAsync {
5757
selector: 'list-test-async-filter',
5858
styleUrls: ['examples/list/styles.css'],
5959
providers: [DataService],
60-
// changeDetection: ChangeDetectionStrategy.OnPush,
60+
changeDetection: ChangeDetectionStrategy.OnPush,
6161
template: `
6262
<GridLayout rows="auto * auto" columns="* *">
6363
<Label text="ListView" class="list-title"></Label>
@@ -66,15 +66,15 @@ export class ListTestAsync {
6666
<ListView row="1" [items]="filteredItems$ | async" (itemTap)="onItemTap($event)" margin="10">
6767
<template let-item="item" let-i="index" let-odd="odd" let-even="even">
6868
<StackLayout [class.odd]="odd" [class.even]="even">
69-
<Label [text]='"index: " + item.name'></Label>
69+
<Label [text]='"name: " + item.name'></Label>
7070
</StackLayout>
7171
</template>
7272
</ListView>
7373
7474
<StackLayout row="1" col="1" margin="10">
7575
<StackLayout *ngFor="let item of (filteredItems$ | async); let odd = odd; let even = even"
7676
[class.odd]="odd" [class.even]="even" marginBottom="1">
77-
<Label [text]='"index: " + item.name'></Label>
77+
<Label [text]='"name: " + item.name'></Label>
7878
</StackLayout>
7979
</StackLayout>
8080

ng-sample/app/examples/list/list-test.ts

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,80 +8,70 @@ class DataItem {
88

99
@Component({
1010
selector: 'item-component',
11-
styleUrls: ['examples/list/styles.css'],
12-
// changeDetection: ChangeDetectionStrategy.OnPush,
11+
styleUrls: ['examples/list/styles.css'],
12+
changeDetection: ChangeDetectionStrategy.OnPush,
1313
template: `
1414
<StackLayout [class.odd]="odd" [class.even]="even">
15-
<Label [text]='"[" + data.id + "]:" + data.name'></Label>
15+
<Label [text]='"index: " + index'></Label>
16+
<Label [text]='"[" + data.id +"]" + data.name'></Label>
1617
</StackLayout>
1718
`
1819
})
19-
export class ItemComponent implements AfterViewChecked,DoCheck {
20+
export class ItemComponent implements AfterViewChecked, DoCheck {
2021
@Input() data: DataItem;
2122
@Input() odd: boolean;
2223
@Input() even: boolean;
24+
@Input() index: boolean;
2325
constructor() { }
2426

25-
ngDoCheck(){
26-
// console.log("ItemComponent.ngDoCheck: " + this.data.id);
27+
ngDoCheck() {
28+
console.log("ItemComponent.ngDoCheck: " + this.data.id);
2729
}
2830

29-
ngAfterViewChecked(){
30-
// console.log("ItemComponent.ngAfterViewChecked: " + this.data.id);
31+
ngAfterViewChecked() {
32+
console.log("ItemComponent.ngAfterViewChecked: " + this.data.id);
3133
}
3234
}
3335

3436
@Component({
3537
selector: 'list-test',
3638
styleUrls: ['examples/list/styles.css'],
3739
directives: [ItemComponent],
38-
// changeDetection: ChangeDetectionStrategy.OnPush,
40+
changeDetection: ChangeDetectionStrategy.OnPush,
3941
template: `
40-
<GridLayout rows="auto * auto" columns="* *">
42+
<GridLayout rows="auto * auto">
4143
<Label text="ListView" class="list-title"></Label>
42-
<Label text="*ngFor" class="list-title" col="1"></Label>
4344
4445
<ListView [items]="myItems" (itemTap)="onItemTap($event)" row="1" margin="10">
4546
<template let-item="item" let-i="index" let-odd="odd" let-even="even">
46-
<item-component [data]="item" [odd]="odd" [even]="even"></item-component>
47+
<item-component [data]="item" [odd]="odd" [even]="even" [index]="i"></item-component>
4748
</template>
4849
</ListView>
49-
<StackLayout row="1" col="1" margin="10">
50-
<StackLayout *ngFor="let item of myItems; let odd = odd; let even = even"
51-
[class.odd]="odd" [class.even]="even" marginBottom="1">
52-
<item-component [data]="item" [odd]="odd" [even]="even"></item-component>
53-
</StackLayout>
54-
</StackLayout>
5550
56-
<StackLayout row="2" colspan="2" orientation="horizontal">
57-
<Button text="add item" (tap)="addItem()" ></Button>
58-
<Button text="tap" (tap)="justTap()" ></Button>
59-
</StackLayout>
51+
<Button text="add item" (tap)="addItem()" row="2" ></Button>
6052
</GridLayout>
6153
`
6254
// TEMPLATE WITH COMPONENT
6355
// <template let-item="item" let-i="index" let-odd="odd" let-even="even">
6456
// <item-component [data]="item" [odd]='odd' [even]='even'></item-component>
6557
// </template>
66-
58+
6759
// IN-PLACE TEMPLATE
68-
// <template let-item="item" let-i="index" let-odd="odd" let-even="even">
60+
// <template let-data="item" let-i="index" let-odd="odd" let-even="even">
6961
// <StackLayout [class.odd]="odd" [class.even]="even">
7062
// <Label [text]='"index: " + i'></Label>
71-
// <Label [text]='"[" + item.id +"]" + item.name'></Label>
63+
// <Label [text]='"[" + data.id +"]" + data.name'></Label>
7264
// </StackLayout>
7365
// </template>
7466
})
7567
export class ListTest {
76-
//public myItems: ObservableArray<DataItem>;
7768
public myItems: Array<DataItem>;
7869
private counter: number;
7970

8071
constructor() {
81-
//this.myItems = new ObservableArray<DataItem>();
8272
this.myItems = [];
8373
this.counter = 0;
84-
for (var i = 0; i < 2; i++) {
74+
for (var i = 0; i < 100; i++) {
8575
this.myItems.push(new DataItem(i, "data item " + i));
8676
this.counter = i;
8777
}
@@ -90,13 +80,9 @@ export class ListTest {
9080
public onItemTap(args) {
9181
console.log("--> ItemTapped: " + args.index);
9282
}
93-
83+
9484
addItem() {
9585
this.counter++;
9686
this.myItems.push(new DataItem(this.counter, "data item " + this.counter));
9787
}
98-
99-
justTap() {
100-
console.log("----------------- TAP -----------------");
101-
}
10288
}

0 commit comments

Comments
 (0)