Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ng-sample/app/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ button {
font-size: 42;
horizontal-align: center;
}

.odd {
background-color: hotpink
}

.even {
background-color: lightseagreen;
}
75 changes: 75 additions & 0 deletions ng-sample/app/list-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {Component, Input} from 'angular2/core';

class DataItem {
constructor(public id: number, public name: string) { }
}

@Component({
selector: 'item-component',
template: `
<StackLayout [class.odd]="odd" [class.even]="even">
<Label [text]='"id: " + data.id'></Label>
<Label [text]='"name: " + data.name'></Label>
</StackLayout>
`
})
export class ItemComponent {
@Input() data: DataItem;
@Input() odd: boolean;
@Input() even: boolean;
constructor() { }
}

@Component({
selector: 'list-test',
directives: [ItemComponent],
template: `
<GridLayout rows="auto, *, auto">
<Label row="0" text="-==START==-" fontSize="20"></Label>

<GridLayout row="1">

<ListView [items]="myItems" (itemTap)="onItemTap($event)">
<item-template>
<template #item="item" #i="index" #odd="odd" #even="even">
<StackLayout [class.odd]="odd" [class.even]="even">
<Label [text]='"index: " + index'></Label>
<Label [text]='"[" + item.id +"]" + item.name'></Label>
</StackLayout>
</template>
</item-template>
</ListView>

</GridLayout>

<Label row="2" text="-==END==-" fontSize="20"></Label>
</GridLayout>
`
// TEMPLATE WITH COMPONENT
// <template #item="item" #i="index" #odd="odd" #even="even">
// <item-component [data]="item" [odd]='odd' [even]='even'></item-component>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does using the item-component not work?

// </template>

// IN-PLACE TEMPLATE
// <template #item="item" #i="index" #odd="odd" #even="even">
// <StackLayout [class.odd]="odd" [class.even]="even">
// <Label [text]='"index: " + i'></Label>
// <Label [text]='"[" + item.id +"]" + item.name'></Label>
// </StackLayout>
// </template>
})
export class ListTest {
public myItems: Array<DataItem>;

constructor() {
this.myItems = [];
for (var i = 0; i < 30; i++) {
this.myItems.push(new DataItem(i, "data item " + i));
}
}

public onItemTap(args) {
console.log("------------------------ ItemTapped: " + args.index);
}
}

6 changes: 4 additions & 2 deletions ng-sample/app/main-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import {TextView} from 'ui/text-view';
import {Page} from 'ui/page';

import {nativeScriptBootstrap} from './nativescript-angular/application';
import {RendererTest} from './renderer-test';
// import {RendererTest} from './renderer-test';
//import {Benchmark} from './benchmark';
import {ListTest} from './list-test';

export function createPage() {
var page = new Page();
Expand All @@ -17,7 +18,8 @@ export function createPage() {
profiling.start('ng-bootstrap');
console.log('BOOTSTRAPPING...');
//nativeScriptBootstrap(Benchmark, []).then((appRef) => {
nativeScriptBootstrap(RendererTest, []).then((appRef) => {
// nativeScriptBootstrap(RendererTest, []).then((appRef) => {
nativeScriptBootstrap(ListTest, []).then((appRef) => {
profiling.stop('ng-bootstrap');
console.log('ANGULAR BOOTSTRAP DONE.');
}, (err) =>{
Expand Down
1 change: 1 addition & 0 deletions ng-sample/references.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference path="./node_modules/tns-core-modules/tns-core-modules.d.ts" /> Needed for autocompletion and compilation.
26 changes: 4 additions & 22 deletions ng-sample/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,12 @@
"emitDecoratorMetadata": true,
"noEmitOnError": true
},
"files": [
"app/app.ts",
"app/benchmark.ts",
"app/global.d.ts",
"app/main-page.ts",
"app/main-view-model.ts",
"app/nativescript-angular/application.d.ts",
"app/nativescript-angular/application.ts",
"app/nativescript-angular/dom_adapter.ts",
"app/nativescript-angular/element-registry.d.ts",
"app/nativescript-angular/element-registry.ts",
"app/nativescript-angular/polyfills/array.ts",
"app/nativescript-angular/renderer.ts",
"app/nativescript-angular/view_node.ts",
"app/nativescript-angular/xhr.ts",
"app/nativescript-angular/zone.ts",
"app/nativescript-angular/zone_patch.ts",
"app/profiling.ts",
"app/renderer-test.ts",
"app/starter.ts",
"node_modules/tns-core-modules/tns-core-modules.d.ts"
],
"filesGlob": [
"node_modules/tns-core-modules/tns-core-modules.d.ts",
"app/**/*.ts"
],
"exclude": [
"node_modules",
"platforms"
]
}
2 changes: 2 additions & 0 deletions src/nativescript-angular/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {APPLICATION_COMMON_PROVIDERS} from 'angular2/src/core/application_common
import {COMPILER_PROVIDERS} from 'angular2/src/compiler/compiler';
import {PLATFORM_COMMON_PROVIDERS} from 'angular2/src/core/platform_common_providers';
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from "angular2/common";
import {NS_DIRECTIVES} from './directives/ns-directives';

import {bootstrap as angularBootstrap} from 'angular2/bootstrap';

Expand All @@ -41,6 +42,7 @@ export function nativeScriptBootstrap(appComponentType: any,

provide(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}),
provide(PLATFORM_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}),
provide(PLATFORM_DIRECTIVES, {useValue: NS_DIRECTIVES, multi: true}),

APPLICATION_COMMON_PROVIDERS,
COMPILER_PROVIDERS,
Expand Down
90 changes: 90 additions & 0 deletions src/nativescript-angular/directives/list-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {HostListener, Host, Directive, Component, ContentChild, ViewRef, TemplateRef, ViewContainerRef} from 'angular2/core';
import {View} from 'ui';
import {ViewNode, DummyViewNode} from '../view_node';

const NG_VIEW = "_ngViewRef";

@Directive({
selector: 'ListView',
})
export class ListViewDirective {
private itemTemplate: ListItemTemplate;
public registerItemTemplate(container: ListItemTemplate) {
this.itemTemplate = container;
}

@HostListener("itemLoading", ['$event'])
public onItemLoading(args) {
if (!this.itemTemplate) {
return;
}

let index = args.index;
let items = args.object.items;
let currentItem = typeof (items.getItem) === "function" ? items.getItem(index) : items[index];
let viewRef: ViewRef;

if (args.view) {
console.log("ListView.onItemLoading: " + index + " - Reusing exisiting view");
viewRef = args.view[NG_VIEW];
}
else {
console.log("ListView.onItemLoading: " + index + " - Creating view from template");
viewRef = this.itemTemplate.instantiateTemplate();
args.view = getSingleViewFromViewRef(viewRef);
args.view[NG_VIEW] = viewRef;
}
this.setupViewRef(viewRef, currentItem, index);
}

public setupViewRef(viewRef: ViewRef, data: any, index: number): void {
viewRef.setLocal('\$implicit', data.item);
viewRef.setLocal("item", data);
viewRef.setLocal("index", index);
viewRef.setLocal('even', (index % 2 == 0));
viewRef.setLocal('odd', (index % 2 == 1));
}
}

@Component({
selector: 'item-template',
template: ``,
})
export class ListItemTemplate {
@ContentChild(TemplateRef) template: TemplateRef;

constructor(
@Host() listDirective: ListViewDirective,
private _viewContainer: ViewContainerRef) {

listDirective.registerItemTemplate(this);
}

public instantiateTemplate(): ViewRef {
return this._viewContainer.createEmbeddedView(this.template);
}
}

function getSingleViewFromViewRef(viewRef: ViewRef): View {
// Hacky Hacky Hacky !!!
var getSingleViewRecursive = (nodes: Array<ViewNode>, nestLevel: number) => {
var actualNodes = nodes.filter((n) => !(n instanceof DummyViewNode));

if (actualNodes.length === 0) {
throw new Error("No suitable views found in list template! Nesting level: " + nestLevel);
}
else if (actualNodes.length > 1) {
throw new Error("More than one view found in list template! Nesting level: " + nestLevel);
}
else {
if (actualNodes[0].nativeView) {
return actualNodes[0].nativeView;
}
else {
return getSingleViewRecursive(actualNodes[0].children, nestLevel + 1)
}
}
}

return getSingleViewRecursive((<any>viewRef).renderFragment.nodes, 0);
}
4 changes: 4 additions & 0 deletions src/nativescript-angular/directives/ns-directives.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {Type} from 'angular2/src/facade/lang';
import {ListItemTemplate, ListViewDirective} from './list-view';

export const NS_DIRECTIVES: Type[] = [ListItemTemplate, ListViewDirective];
4 changes: 2 additions & 2 deletions src/nativescript-angular/view_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ export class ViewNode {
// complex property - we will deal with this in postAttachUI()
}
else {
console.log('parentNativeView: ' + this.parentNativeView);
throw new Error("Parent view can't have children! " + this.parentNativeView);
// Child adding will be handled elsewhere. For example ListView
console.log('Child not added for parent. child: ' + this.viewName + ', parent: ' + this.parentNativeView);
}
}

Expand Down