FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add Template factory function and use it in the Repeater and ListView… · NativeScript/NativeScript@ee6b7eb · GitHub

Commit ee6b7eb

Browse files
committed
Add Template factory function and use it in the Repeater and ListView components
1 parent e7a7165 commit ee6b7eb

13 files changed

Lines changed: 112 additions & 25 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Page xmlns="http://schemas.nativescript.org/tns.xsd"
2+
xmlns:tc="xml-declaration/template-builder-tests/template-view">
3+
<tc:TemplateView id="template-view">
4+
<tc:TemplateView.template>
5+
<Button text="Click!" />
6+
</tc:TemplateView.template>
7+
</tc:TemplateView>
8+
</Page>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { View, Template } from "ui/core/view"
2+
import { PropertyChangeData, Property, PropertyMetadataSettings } from "ui/core/dependency-observable"
3+
import * as proxy from "ui/core/proxy"
4+
import { LayoutBase } from "ui/layouts/layout-base"
5+
import { parse } from "ui/builder"
6+
7+
export module knownTemplates {
8+
export var template = "template";
9+
}
10+
11+
export class TemplateView extends LayoutBase {
12+
public static templateProperty = new Property(
13+
"template",
14+
"TemplateView",
15+
new proxy.PropertyMetadata(
16+
undefined,
17+
PropertyMetadataSettings.AffectsLayout,
18+
null
19+
)
20+
);
21+
22+
get template(): string | Template {
23+
return this._getValue(TemplateView.templateProperty);
24+
}
25+
26+
set template(value: string | Template) {
27+
this._setValue(TemplateView.templateProperty, value);
28+
}
29+
30+
public parseTemplate() {
31+
this.addChild(parse(this.template));
32+
}
33+
}

‎apps/tests/xml-declaration/xml-declaration-tests.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import stackLayoutModule = require("ui/layouts/stack-layout");
1414
import {Label} from "ui/label";
1515
import {Page} from "ui/page";
1616
import {Button} from "ui/button";
17+
import {View} from "ui/core/view";
18+
import {TemplateView} from "./template-builder-tests/template-view";
1719
import myCustomControlWithoutXml = require("./mymodule/MyControl");
1820
import listViewModule = require("ui/list-view");
1921
import helper = require("../ui/helper");
@@ -818,4 +820,19 @@ export function test_searchbar_donotcrash_whentext_isspace() {
818820
var sb = <searchBarModule.SearchBar>p.content;
819821

820822
TKUnit.assertEqual(sb.text, " ");
821-
};
823+
};
824+
825+
export function test_parse_template_property() {
826+
var page = <Page>builder.load(fs.path.join(__dirname, "template-builder-tests/simple-template-test.xml"));
827+
TKUnit.assert(page, "Expected root page.");
828+
var templateView = <TemplateView>page.getViewById("template-view");
829+
TKUnit.assert(templateView, "Expected TemplateView.");
830+
TKUnit.assert(templateView.template, "Expected the template of the TemplateView to be defined");
831+
832+
TKUnit.assertEqual(templateView.getChildrenCount(), 0, "Expected TemplateView initially to have no children.");
833+
templateView.parseTemplate();
834+
TKUnit.assertEqual(templateView.getChildrenCount(), 1, "Expected TemplateView initially to have 1 child.");
835+
var button = <Button>templateView.getChildAt(0);
836+
TKUnit.assert(button, "Expected the TemplateView's template to create a button child.");
837+
TKUnit.assertEqual(button.text, "Click!", "Expected child Button to have text 'Click!'");
838+
}

‎tsconfig.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@
320320
"apps/tests/xml-declaration/mymodule/MyControl.ts",
321321
"apps/tests/xml-declaration/mymodulewithxml/MyControl.ts",
322322
"apps/tests/xml-declaration/xml-declaration-tests.ts",
323+
"apps/tests/xml-declaration/template-builder-tests/template-view.ts",
323324
"apps/tests/xml-parser-tests/xml-parser-tests.ts",
324325
"apps/transforms/app.ts",
325326
"apps/transforms/main-page.ts",

‎ui/builder/builder.d.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
export function load(fileName: string, exports?: any): view.View;
66
export function load(options: LoadOptions): view.View;
7-
export function parse(value: string, exports?: any): view.View;
7+
export function parse(value: string | view.Template, exports?: any): view.View;
88

99
export interface LoadOptions {
1010
path: string;

‎ui/builder/builder.ts‎

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,24 @@ function isCurentPlatform(value: string): boolean {
2121
return value && value.toLowerCase() === platform.device.os.toLowerCase();
2222
}
2323

24-
export function parse(value: string, context: any): view.View {
25-
var viewToReturn: view.View;
26-
27-
if (context instanceof view.View) {
28-
context = getExports(context);
29-
}
30-
31-
var componentModule = parseInternal(value, context);
32-
33-
if (componentModule) {
34-
viewToReturn = componentModule.component;
24+
export function parse(value: string | view.Template, context: any): view.View {
25+
if (types.isString(value)) {
26+
var viewToReturn: view.View;
27+
28+
if (context instanceof view.View) {
29+
context = getExports(context);
30+
}
31+
32+
var componentModule = parseInternal(<string>value, context);
33+
34+
if (componentModule) {
35+
viewToReturn = componentModule.component;
36+
}
37+
38+
return viewToReturn;
39+
} else if (types.isFunction(value)) {
40+
return (<view.Template>value)();
3541
}
36-
37-
return viewToReturn;
3842
}
3943

4044
function parseInternal(value: string, context: any): componentBuilder.ComponentModule {
@@ -104,6 +108,7 @@ function parseInternal(value: string, context: any): componentBuilder.ComponentM
104108

105109
if (templateBuilderDef.isKnownTemplate(name, parent.exports)) {
106110
templateBuilder = new templateBuilderDef.TemplateBuilder({
111+
context: parent ? getExports(parent.component) : null, // Passing 'context' won't work if you set "codeFile" on the page
107112
parent: parent,
108113
name: name,
109114
elementName: args.elementName,

‎ui/builder/template-builder.d.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//@private
22
declare module "ui/builder/template-builder" {
33
import xml = require("xml");
4+
import page = require("ui/page");
45
import componentBuilder = require("ui/builder/component-builder");
56

67
class TemplateBuilder {
@@ -18,6 +19,7 @@ declare module "ui/builder/template-builder" {
1819
export function isKnownTemplate(name: string, exports: any): boolean;
1920

2021
interface TemplateProperty {
22+
context?: any;
2123
parent: componentBuilder.ComponentModule;
2224
name: string;
2325
elementName: string;

‎ui/builder/template-builder.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import definition = require("ui/builder/template-builder");
2+
import builder = require("ui/builder");
3+
import view = require("ui/core/view");
4+
import page = require("ui/page");
25
import xml = require("xml");
36

47
var KNOWNTEMPLATES = "knownTemplates";
58

69
export class TemplateBuilder {
10+
private _context: any;
711
private _items: Array<string>;
812
private _templateProperty: definition.TemplateProperty;
913
private _nestingLevel: number;
1014

1115
constructor(templateProperty: definition.TemplateProperty) {
16+
this._context = templateProperty.context;
1217
this._items = new Array<string>();
1318
this._templateProperty = templateProperty;
1419
this._nestingLevel = 0;
@@ -56,7 +61,10 @@ export class TemplateBuilder {
5661

5762
private build() {
5863
if (this._templateProperty.name in this._templateProperty.parent.component) {
59-
this._templateProperty.parent.component[this._templateProperty.name] = this._items.join("");
64+
var xml = this._items.join("");
65+
var context = this._context;
66+
var template: view.Template = () => builder.parse(xml, context);
67+
this._templateProperty.parent.component[this._templateProperty.name] = template;
6068
}
6169
}
6270
}

‎ui/core/view.d.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,18 @@ declare module "ui/core/view" {
511511
*/
512512
export class CustomLayoutView extends View {
513513
}
514+
515+
/**
516+
* Defines an interface for a View factory function.
517+
* Commonly used to specify the visualization of data objects.
518+
*/
519+
interface Template {
520+
/**
521+
* Call signature of the factory function.
522+
* Returns a new View instance.
523+
*/
524+
(): View;
525+
}
514526

515527
/**
516528
* Defines an interface for adding arrays declared in xml.

‎ui/list-view/list-view-common.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import builder = require("ui/builder");
88
import label = require("ui/label");
99
import color = require("color");
1010
import weakEvents = require("ui/core/weak-event-listener");
11+
import types = require("utils/types");
1112

1213
var ITEMS = "items";
1314
var ITEMTEMPLATE = "itemTemplate";
@@ -91,10 +92,10 @@ export class ListView extends view.View implements definition.ListView {
9192
this._setValue(ListView.itemsProperty, value);
9293
}
9394

94-
get itemTemplate(): string {
95+
get itemTemplate(): string | view.Template {
9596
return this._getValue(ListView.itemTemplateProperty);
9697
}
97-
set itemTemplate(value: string) {
98+
set itemTemplate(value: string | view.Template) {
9899
this._setValue(ListView.itemTemplateProperty, value);
99100
}
100101

@@ -132,7 +133,7 @@ export class ListView extends view.View implements definition.ListView {
132133
var v;
133134

134135
if (this.itemTemplate && this.items) {
135-
v = builder.parse(this.itemTemplate, this);
136+
v = builder.parse(this.itemTemplate);
136137
}
137138

138139
return v;

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL