Skip to content

Commit

Permalink
fix(list-view): Destroy item views on unload
Browse files Browse the repository at this point in the history
  • Loading branch information
hdeshev committed Mar 16, 2017
1 parent 0bd2ba5 commit 71301aa
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
20 changes: 15 additions & 5 deletions nativescript-angular/directives/list-view-comp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
listViewLog("registerTemplate for key: " + key);

const viewRef = this.loader.createEmbeddedView(template, new ListItemContext(), 0);
const resultView = getSingleViewFromViewRef(viewRef);
const resultView = getItemViewRoot(viewRef);
resultView[NG_VIEW] = viewRef;

return resultView;
Expand Down Expand Up @@ -170,7 +170,7 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
} else {
listViewLog("onItemLoading: " + index + " - Creating view from template");
viewRef = this.loader.createEmbeddedView(this.itemTemplate, new ListItemContext(), 0);
args.view = getSingleViewFromViewRef(viewRef);
args.view = getItemViewRoot(viewRef);
args.view[NG_VIEW] = viewRef;
}

Expand Down Expand Up @@ -215,7 +215,7 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
}
}

function getSingleViewRecursive(nodes: Array<any>, nestLevel: number) {
function getSingleViewRecursive(nodes: Array<any>, nestLevel: number): View {
const actualNodes = nodes.filter((n) => !!n && n.nodeName !== "#text");

if (actualNodes.length === 0) {
Expand All @@ -235,8 +235,18 @@ function getSingleViewRecursive(nodes: Array<any>, nestLevel: number) {
}
}

function getSingleViewFromViewRef(viewRef: EmbeddedViewRef<any>): View {
return getSingleViewRecursive(viewRef.rootNodes, 0);
export interface ComponentView {
rootNodes: Array<any>;
destroy(): void;
};
export type RootLocator = (nodes: Array<any>, nestLevel: number) => View;

export function getItemViewRoot(viewRef: ComponentView, rootLocator: RootLocator = getSingleViewRecursive): View {
const rootView = rootLocator(viewRef.rootNodes, 0);
rootView.on("unloaded", () => {
viewRef.destroy();
});
return rootView;
}

@Directive({ selector: "[nsTemplateKey]" })
Expand Down
29 changes: 23 additions & 6 deletions tests/app/tests/list-view-tests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assert } from "./test-config";
import { Component, Input, AfterViewInit } from '@angular/core';
import { Component, Input, AfterViewInit } from "@angular/core";
import { TestApp } from "./test-app";
import { RootLocator, ComponentView, getItemViewRoot } from "nativescript-angular/directives/list-view-comp";
import { ProxyViewContainer } from "tns-core-modules/ui/proxy-view-container";

// import trace = require("trace");
// trace.setCategories("ns-list-view, " + trace.categories.Navigation);
Expand All @@ -20,7 +22,7 @@ const ITEMS = [
let testTemplates: { first: number, second: number };

@Component({
selector: 'list-view-setupItemView',
selector: "list-view-setupItemView",
template: `
<GridLayout>
<ListView [items]="myItems" (setupItemView)="onSetupItemView($event)">
Expand Down Expand Up @@ -61,7 +63,6 @@ export class ItemTemplateComponent {
<template nsTemplateKey="first">
<item-component templateName="first"></item-component>
</template>
<template nsTemplateKey="second" let-item="item">
<item-component templateName="second"></item-component>
</template>
Expand All @@ -77,7 +78,7 @@ export class TestListViewSelectorComponent {
constructor() { testTemplates = { first: 0, second: 0 }; }
}

describe('ListView-tests', () => {
describe("ListView-tests", () => {
let testApp: TestApp = null;

before(() => {
Expand All @@ -94,7 +95,7 @@ describe('ListView-tests', () => {
testApp.disposeComponents();
});

it('setupItemView is called for every item', (done) => {
it("setupItemView is called for every item", (done) => {
return testApp.loadComponent(TestListViewComponent).then((componentRef) => {
const component = componentRef.instance;
setTimeout(() => {
Expand All @@ -106,7 +107,7 @@ describe('ListView-tests', () => {
});


it('itemTemplateSelector selects templates', (done) => {
it("itemTemplateSelector selects templates", (done) => {
return testApp.loadComponent(TestListViewSelectorComponent).then((componentRef) => {
setTimeout(() => {
assert.deepEqual(testTemplates, { first: 2, second: 1 });
Expand All @@ -116,3 +117,19 @@ describe('ListView-tests', () => {
.catch(done);
});
});

describe("ListView item templates", () => {
it("destroy child ng views on unload", () => {
const childRoot = new ProxyViewContainer();
let viewDestroyed = false;
const view: ComponentView = {
rootNodes: [],
destroy: () => {
viewDestroyed = true;
}
};
const itemRoot = getItemViewRoot(view, (_rootNodes, _level) => childRoot);
itemRoot.notify({eventName: "unloaded", object: itemRoot});
assert.isTrue(viewDestroyed, "ng view not destroyed");
});
});

0 comments on commit 71301aa

Please sign in to comment.