Merge pull request #556 from hdeshev/view-getpage

Fix applying app CSS to template children when using custom pages.
This commit is contained in:
Hristo Deshev
2015-08-07 18:55:30 +03:00
17 changed files with 140 additions and 86 deletions

View File

@@ -3,7 +3,7 @@ import view = require("ui/core/view");
var toggle = false;
export function toggleTap(args) {
var page = <pages.Page>view.getAncestor(<view.View>args.object, "Page")
var page = <pages.Page>(<view.View>args.object).page;
page.actionBarHidden = toggle;
toggle = !toggle;
}
}

View File

@@ -24,7 +24,7 @@ export function pageLoaded(args) {
}
var i = 0;
export function buttonTap(args) {
var page = <pages.Page>view.getAncestor(<view.View>args.object, "Page")
var page = <pages.Page>(<view.View>args.object).page;
var vm = page.bindingContext;
var icon;
if (i % 3 === 0) {

View File

@@ -5,7 +5,7 @@ import view = require("ui/core/view");
var i = 0;
export function buttonTap(args: observable.EventData) {
var page = <pages.Page>view.getAncestor(<view.View>args.object, "Page")
var page = <pages.Page>(<view.View>args.object).page;
var navBtn = new action.NavigationButton();
navBtn.text = "nav " + i++;
@@ -26,7 +26,7 @@ export function buttonTap(args: observable.EventData) {
var j = 0;
export function visibilityTap(args: observable.EventData) {
var page = <pages.Page>view.getAncestor(<view.View>args.object, "Page")
var page = <pages.Page>(<view.View>args.object).page;
if (page.actionBar.android) {
if (j % 3 === 0) {

View File

@@ -4,7 +4,7 @@ import view = require("ui/core/view");
var i = 0;
export function buttonTap(args: observable.EventData) {
var page = <pages.Page>view.getAncestor(<view.View>args.object, "Page")
var page = <pages.Page>(<view.View>args.object).page;
page.actionBar.title = "Title changed " + i++;
if (page.actionBar.android) {
@@ -22,7 +22,7 @@ export function buttonTap(args: observable.EventData) {
var j = 0;
export function visibilityTap(args: observable.EventData) {
var page = <pages.Page>view.getAncestor(<view.View>args.object, "Page")
var page = <pages.Page>(<view.View>args.object).page;
if (page.actionBar.android) {
if (j % 3 === 0) {

View File

@@ -188,11 +188,11 @@ export function assertEqual(actual: any, expected: any, message?: string) {
// Use the equals method
if (!actual.equals(expected)) {
throw new Error(message + " Actual: " + actual + " Expected: " + expected);
throw new Error(`${message} Actual: <${actual}>(${typeof(actual)}). Expected: <${expected}>(${typeof(expected)})`);
}
}
else if (actual !== expected) {
throw new Error(message + " Actual: " + actual + " Expected: " + expected);
throw new Error(`${message} Actual: <${actual}>(${typeof(actual)}). Expected: <${expected}>(${typeof(expected)})`);
}
};

View File

@@ -2,12 +2,12 @@ import view = require("ui/core/view");
import pages = require("ui/page");
export function applyTap(args) {
var page = <pages.Page>view.getAncestor(args.object, "Page");
var page = <pages.Page>(<view.View>args.object).page;
var css = "#test-element { " + args.object.tag + " }";
page.css = css;
}
export function resetTap(args) {
var page = <pages.Page>view.getAncestor(args.object, "Page");
var page = <pages.Page>(<view.View>args.object).page;
page.css = "";
}
}

View File

@@ -465,7 +465,7 @@ export function test_usingAppLevelConvertersInListViewItems() {
var dateConverter = function (value, format) {
var result = format;
var day = value.getDate();
result = result.replace("DD", month < 10 ? "0" + day : day);
result = result.replace("DD", day < 10 ? "0" + day : day);
var month = value.getMonth() + 1;
result = result.replace("MM", month < 10 ? "0" + month : month);
result = result.replace("YYYY", value.getFullYear());
@@ -475,8 +475,7 @@ export function test_usingAppLevelConvertersInListViewItems() {
app.resources["dateConverter"] = dateConverter;
var data = new observableArray.ObservableArray();
data.push({ date: new Date() });
data.push({ date: new Date(2020, 2, 7) });
function testAction(views: Array<viewModule.View>) {
listView.itemTemplate = "<Label id=\"testLabel\" text=\"{{ date, date | dateConverter('DD.MM.YYYY') }}\" />";
@@ -485,7 +484,7 @@ export function test_usingAppLevelConvertersInListViewItems() {
TKUnit.wait(ASYNC);
var nativeElementText = getTextFromNativeElementAt(listView, 0);
TKUnit.assertEqual(nativeElementText, dateConverter(new Date(), "DD.MM.YYYY"), "native element");
TKUnit.assertEqual(nativeElementText, "07.03.2020", "native element text");
};
helper.buildUIAndRunTest(listView, testAction);

View File

@@ -0,0 +1,4 @@
import {Page} from "ui/page";
export class InheritedPage extends Page {
}

View File

@@ -0,0 +1,7 @@
import {Page} from "ui/page";
import {Label} from "ui/label";
export function pageLoaded(args) {
var page = <Page>args.object;
(<Label>page.content).text += " and loaded";
}

View File

@@ -0,0 +1,4 @@
<inherited:InheritedPage xmlns="http://www.nativescript.org/tns.xsd"
xmlns:inherited="xml-declaration/inherited-base-page" loaded="pageLoaded">
<Label text="Inherited" />
</inherited:InheritedPage>

View File

@@ -1,7 +1,6 @@
import TKUnit = require("../TKUnit");
import view = require("ui/core/view");
import builder = require("ui/builder");
import page = require("ui/page");
import buttonModule = require("ui/button");
import switchModule = require("ui/switch");
import textFieldModule = require("ui/text-field");
@@ -12,7 +11,8 @@ import fs = require("file-system");
import fileSystemAccess = require("file-system/file-system-access");
import observable = require("data/observable");
import stackLayoutModule = require("ui/layouts/stack-layout");
import labelModule = require("ui/label");
import {Label} from "ui/label";
import {Page} from "ui/page";
import myCustomControlWithoutXml = require("./mymodule/MyControl");
import listViewModule = require("ui/list-view");
import helper = require("../ui/helper");
@@ -52,9 +52,9 @@ export function test_loadWithOptionsNoXML() {
};
export function test_loadWithOptionsNoXML_CSSIsApplied() {
var newPage: page.Page;
var pageFactory = function (): page.Page {
newPage = new page.Page();
var newPage: Page;
var pageFactory = function (): Page {
newPage = new Page();
newPage.content = builder.load({
path: "~/xml-declaration/mymodule",
@@ -76,6 +76,22 @@ export function test_loadWithOptionsNoXML_CSSIsApplied() {
}
};
export function test_loadInheritedPageAndResolveFromChild() {
helper.navigateToModuleAndRunTest("./xml-declaration/inherited-page", null, (page) => {
let contentLabel = <Label>page.content;
TKUnit.assertEqual("Inherited and loaded", contentLabel.text);
let discoveredPage = contentLabel.page;
TKUnit.assert(page === discoveredPage);
let discoveredAncestorByBaseType = viewModule.getAncestor(contentLabel, Page);
TKUnit.assert(page === discoveredAncestorByBaseType);
let discoveredAncestorByInheritedTypeName = viewModule.getAncestor(contentLabel, "InheritedPage");
TKUnit.assert(page === discoveredAncestorByInheritedTypeName);
});
}
export function test_loadWithOptionsWithXML() {
var v = builder.load({
path: "~/xml-declaration/mymodulewithxml",
@@ -86,9 +102,9 @@ export function test_loadWithOptionsWithXML() {
};
export function test_loadWithOptionsWithXML_CSSIsApplied() {
var newPage: page.Page;
var pageFactory = function (): page.Page {
newPage = new page.Page();
var newPage: Page;
var pageFactory = function (): Page {
newPage = new Page();
newPage.content = builder.load({
path: "~/xml-declaration/mymodulewithxml",
@@ -116,7 +132,7 @@ export function test_loadWithOptionsFromTNS() {
name: "Label"
});
TKUnit.assert(v instanceof labelModule.Label, "Expected result: Label; Actual result: " + v + ";");
TKUnit.assert(v instanceof Label, "Expected result: Label; Actual result: " + v + ";");
};
export function test_loadWithOptionsFromTNSPath() {
@@ -125,7 +141,7 @@ export function test_loadWithOptionsFromTNSPath() {
name: "Label"
});
TKUnit.assert(v instanceof labelModule.Label, "Expected result: Label; Actual result: " + v + ";");
TKUnit.assert(v instanceof Label, "Expected result: Label; Actual result: " + v + ";");
};
export function test_parse_ShouldNotCrashWithoutExports() {
@@ -163,7 +179,7 @@ export function test_parse_ShouldFindEventHandlersInExports() {
};
export function test_parse_ShouldSetGridAttachedProperties() {
var p = <page.Page>builder.parse("<Page><GridLayout><Label row='1' col='2' rowSpan='3' colSpan='4' /></GridLayout></Page>");
var p = <Page>builder.parse("<Page><GridLayout><Label row='1' col='2' rowSpan='3' colSpan='4' /></GridLayout></Page>");
var grid = <gridLayoutModule.GridLayout>p.content;
var child = grid.getChildAt(0);
@@ -181,7 +197,7 @@ export function test_parse_ShouldSetGridAttachedProperties() {
};
export function test_parse_ShouldSetCanvasAttachedProperties() {
var p = <page.Page>builder.parse("<Page><AbsoluteLayout><Label left='1' top='2' right='3' bottom='4' /></AbsoluteLayout></Page>");
var p = <Page>builder.parse("<Page><AbsoluteLayout><Label left='1' top='2' right='3' bottom='4' /></AbsoluteLayout></Page>");
var grid = <gridLayoutModule.GridLayout>p.content;
var child = grid.getChildAt(0);
@@ -193,34 +209,34 @@ export function test_parse_ShouldSetCanvasAttachedProperties() {
};
export function test_parse_ShouldParseNumberProperties() {
var p = <page.Page>builder.parse("<Page width='100' />");
var p = <Page>builder.parse("<Page width='100' />");
TKUnit.assert(p.width === 100, "Expected result: 100; Actual result: " + p.width + "; type: " + typeof (p.width));
};
export function test_parse_ShouldParseBooleanProperties() {
var p = <page.Page>builder.parse("<Page><Switch checked='true' /></Page>");
var p = <Page>builder.parse("<Page><Switch checked='true' /></Page>");
var sw = <switchModule.Switch>p.content;
TKUnit.assert(sw.checked === true, "Expected result: true; Actual result: " + sw.checked + "; type: " + typeof (sw.checked));
};
export function test_parse_ShouldParseBooleanPropertiesIgnoreCase() {
var p = <page.Page>builder.parse("<Page><Switch checked='False' /></Page>");
var p = <Page>builder.parse("<Page><Switch checked='False' /></Page>");
var sw = <switchModule.Switch>p.content;
TKUnit.assert(sw.checked === false, "Expected result: false; Actual result: " + sw.checked + "; type: " + typeof (sw.checked));
};
export function test_parse_ShouldParseBooleanPropertiesIgnoreCaseInverted() {
var p = <page.Page>builder.parse("<Page><TextField editable='False' /></Page>");
var p = <Page>builder.parse("<Page><TextField editable='False' /></Page>");
var tf = <textFieldModule.TextField>p.content;
TKUnit.assert(tf.editable === false, "Expected result: false; Actual result: " + tf.editable + "; type: " + typeof (tf.editable));
};
export function test_parse_ShouldParsePlatformSpecificProperties() {
var p = <page.Page>builder.parse("<Page><TextField ios:editable='False' android:editable='True' /></Page>");
var p = <Page>builder.parse("<Page><TextField ios:editable='False' android:editable='True' /></Page>");
var tf = <textFieldModule.TextField>p.content;
if (platform.device.os === platform.platformNames.ios) {
@@ -231,12 +247,12 @@ export function test_parse_ShouldParsePlatformSpecificProperties() {
};
export function test_parse_ShouldParsePlatformSpecificComponents() {
var p = <page.Page>builder.parse("<Page><ios><TextField /></ios><android><Label /></android></Page>");
var p = <Page>builder.parse("<Page><ios><TextField /></ios><android><Label /></android></Page>");
if (platform.device.os === platform.platformNames.ios) {
TKUnit.assert(p.content instanceof textFieldModule.TextField, "Expected result: TextField; Actual result: " + p.content);
}
else {
TKUnit.assert(p.content instanceof labelModule.Label, "Expected result: Label; Actual result: " + p.content);
TKUnit.assert(p.content instanceof Label, "Expected result: Label; Actual result: " + p.content);
}
};
@@ -252,7 +268,7 @@ export function test_parse_ThrowErrorWhenNestingPlatforms() {
};
export function test_parse_ShouldParseBindings() {
var p = <page.Page>builder.parse("<Page><Switch checked='{{ myProp }}' /></Page>");
var p = <Page>builder.parse("<Page><Switch checked='{{ myProp }}' /></Page>");
p.bindingContext = { myProp: true };
var sw = <switchModule.Switch>p.content;
@@ -260,7 +276,7 @@ export function test_parse_ShouldParseBindings() {
};
export function test_parse_ShouldParseBindingsWithObservable() {
var p = <page.Page>builder.parse("<Page><Switch checked='{{ myProp }}' /></Page>");
var p = <Page>builder.parse("<Page><Switch checked='{{ myProp }}' /></Page>");
var obj = new observable.Observable();
obj.set("myProp", true);
p.bindingContext = obj;
@@ -274,7 +290,7 @@ export function test_parse_ShouldParseBindingsWithObservable() {
};
export function test_parse_ShouldParseBindingsToEvents() {
var p = <page.Page>builder.parse("<Page><Button tap='{{ myTap }}' /></Page>");
var p = <Page>builder.parse("<Page><Button tap='{{ myTap }}' /></Page>");
p.bindingContext = {
myTap: function (args) {
//
@@ -286,7 +302,7 @@ export function test_parse_ShouldParseBindingsToEvents() {
};
export function test_parse_ShouldParseBindingsToGestures() {
var p = <page.Page>builder.parse("<Page><Label tap='{{ myTap }}' /></Page>");
var p = <Page>builder.parse("<Page><Label tap='{{ myTap }}' /></Page>");
var context = {
myTap: function (args) {
//
@@ -294,7 +310,7 @@ export function test_parse_ShouldParseBindingsToGestures() {
};
p.bindingContext = context;
var lbl = <labelModule.Label>p.content;
var lbl = <Label>p.content;
var observer = (<view.View>lbl).getGestureObservers(gesturesModule.GestureTypes.tap)[0];
@@ -303,7 +319,7 @@ export function test_parse_ShouldParseBindingsToGestures() {
};
export function test_parse_ShouldParseSubProperties() {
var p = <page.Page>builder.parse("<Page><Switch style.visibility='collapsed' checked='{{ myProp }}' /></Page>");
var p = <Page>builder.parse("<Page><Switch style.visibility='collapsed' checked='{{ myProp }}' /></Page>");
var obj = new observable.Observable();
obj.set("myProp", true);
p.bindingContext = obj;
@@ -315,11 +331,11 @@ export function test_parse_ShouldParseSubProperties() {
export function test_parse_ShouldParseBindingsWithCommaInsideSingleQuote() {
var expected = "Hi,test"
var bindingString = "{{ 'Hi,' + myProp }}";
var p = <page.Page>builder.parse('<Page><Label text="' + bindingString + '" /></Page>');
var p = <Page>builder.parse('<Page><Label text="' + bindingString + '" /></Page>');
var obj = new observable.Observable();
obj.set("myProp", "test");
p.bindingContext = obj;
var lbl = <labelModule.Label>p.content;
var lbl = <Label>p.content;
TKUnit.assert(lbl.text === expected, "Expected " + expected + "; Actual result: " + lbl.text + "; type: " + typeof (lbl.text));
};
@@ -327,17 +343,17 @@ export function test_parse_ShouldParseBindingsWithCommaInsideSingleQuote() {
export function test_parse_ShouldParseBindingsWithCommaInsideDoubleQuote() {
var expected = "Hi,test"
var bindingString = '{{ "Hi," + myProp }}';
var p = <page.Page>builder.parse("<Page><Label text='" + bindingString + "' /></Page>");
var p = <Page>builder.parse("<Page><Label text='" + bindingString + "' /></Page>");
var obj = new observable.Observable();
obj.set("myProp", "test");
p.bindingContext = obj;
var lbl = <labelModule.Label>p.content;
var lbl = <Label>p.content;
TKUnit.assert(lbl.text === expected, "Expected " + expected + "; Actual result: " + lbl.text + "; type: " + typeof (lbl.text));
};
export function test_parse_CanBindBackgroundImage() {
var p = <page.Page>builder.parse("<Page><StackLayout backgroundImage='{{ myProp }}' /></Page>");
var p = <Page>builder.parse("<Page><StackLayout backgroundImage='{{ myProp }}' /></Page>");
var expected = "~/logo.png"
var obj = new observable.Observable();
obj.set("myProp", expected);
@@ -348,81 +364,81 @@ export function test_parse_CanBindBackgroundImage() {
};
export function test_parse_ShouldParseLowerCaseDashedComponentDeclaration() {
var p = <page.Page>builder.parse('<page><stack-layout><label text="Label" /><segmented-bar><segmented-bar.items><segmented-bar-item title="test" /></segmented-bar.items></segmented-bar></stack-layout></page>');
var p = <Page>builder.parse('<page><stack-layout><label text="Label" /><segmented-bar><segmented-bar.items><segmented-bar-item title="test" /></segmented-bar.items></segmented-bar></stack-layout></page>');
var ctrl = <stackLayoutModule.StackLayout>p.content;
TKUnit.assert(ctrl instanceof stackLayoutModule.StackLayout, "Expected result: StackLayout!; Actual result: " + ctrl);
TKUnit.assert(ctrl.getChildAt(0) instanceof labelModule.Label, "Expected result: Label!; Actual result: " + ctrl.getChildAt(0));
TKUnit.assert(ctrl.getChildAt(0) instanceof Label, "Expected result: Label!; Actual result: " + ctrl.getChildAt(0));
TKUnit.assert(ctrl.getChildAt(1) instanceof segmentedBar.SegmentedBar, "Expected result: Label!; Actual result: " + ctrl.getChildAt(0));
};
export function test_parse_ShouldParseCustomComponentWithoutXml() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodule"><customControls:MyControl /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodule"><customControls:MyControl /></Page>');
var ctrl = p.content;
TKUnit.assert(ctrl instanceof myCustomControlWithoutXml.MyControl, "Expected result: custom control is defined!; Actual result: " + ctrl);
};
export function test_parse_ShouldParseCustomComponentWithoutXmlFromTNSModules() {
var p = <page.Page>builder.parse('<Page xmlns' + ':customControls="tns_modules/ui/label"><customControls:Label /></Page>');
var p = <Page>builder.parse('<Page xmlns' + ':customControls="tns_modules/ui/label"><customControls:Label /></Page>');
var ctrl = p.content;
TKUnit.assert(ctrl instanceof labelModule.Label, "Expected result: custom control is defined!; Actual result: " + ctrl);
TKUnit.assert(ctrl instanceof Label, "Expected result: custom control is defined!; Actual result: " + ctrl);
};
export function test_parse_ShouldParseCustomComponentWithoutXmlFromTNSModulesWhenNotSpecified() {
var p = <page.Page>builder.parse('<Page xmlns' + ':customControls="ui/label"><customControls:Label /></Page>');
var p = <Page>builder.parse('<Page xmlns' + ':customControls="ui/label"><customControls:Label /></Page>');
var ctrl = p.content;
TKUnit.assert(ctrl instanceof labelModule.Label, "Expected result: custom control is defined!; Actual result: " + ctrl);
TKUnit.assert(ctrl instanceof Label, "Expected result: custom control is defined!; Actual result: " + ctrl);
};
export function test_parse_ShouldParseCustomComponentWithXml() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:MyControl /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:MyControl /></Page>');
var panel = <stackLayoutModule.StackLayout>p.content;
var lbl = <labelModule.Label>panel.getChildAt(0);
var lbl = <Label>panel.getChildAt(0);
TKUnit.assert(lbl.text === "mymodulewithxml", "Expected result: 'mymodulewithxml'; Actual result: " + lbl);
};
export function test_parse_ShouldParseCustomComponentWithXml_WithAttributes() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:MyControl visibility="collapsed" /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:MyControl visibility="collapsed" /></Page>');
var panel = <stackLayoutModule.StackLayout>p.content;
TKUnit.assertEqual(panel.visibility, "collapsed", "panel.visibility");
};
export function test_parse_ShouldParseCustomComponentWithXml_WithCustomAttributes() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:MyControl myProperty="myValue" /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:MyControl myProperty="myValue" /></Page>');
var panel = <stackLayoutModule.StackLayout>p.content;
TKUnit.assertEqual(panel["myProperty"], "myValue", "customControl.myProperty");
};
export function test_parse_ShouldParseCustomComponentWithXmlNoJS() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:my-control-no-js /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:my-control-no-js /></Page>');
var panel = <stackLayoutModule.StackLayout>p.content;
var lbl = <labelModule.Label>panel.getChildAt(0);
var lbl = <Label>panel.getChildAt(0);
TKUnit.assertEqual(lbl.text, "I'm all about taht XML, no JS", "label.text");
};
export function test_parse_ShouldParseCustomComponentWithXmlNoJS_WithAttributes() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:my-control-no-js visibility="collapsed" /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:my-control-no-js visibility="collapsed" /></Page>');
var panel = <stackLayoutModule.StackLayout>p.content;
TKUnit.assertEqual(panel.visibility, "collapsed", "panel.visibility");
};
export function test_parse_ShouldParseCustomComponentWithXmlNoJS_WithCustomAttributes() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:my-control-no-js myProperty="myValue" /></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodulewithxml"><customControls:my-control-no-js myProperty="myValue" /></Page>');
var panel = <stackLayoutModule.StackLayout>p.content;
TKUnit.assertEqual(panel["myProperty"], "myValue", "customControl.myProperty");
};
export function test_parse_ShouldParseCustomComponentWithoutXmlInListViewTemplate() {
var p = <page.Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodule"><ListView items="{{ items }}" itemLoading="{{ itemLoading }}"><ListView.itemTemplate><customControls:MyControl /></ListView.itemTemplate></ListView></Page>');
var p = <Page>builder.parse('<Page xmlns:customControls="xml-declaration/mymodule"><ListView items="{{ items }}" itemLoading="{{ itemLoading }}"><ListView.itemTemplate><customControls:MyControl /></ListView.itemTemplate></ListView></Page>');
function testAction(views: Array<viewModule.View>) {
var ctrl;
@@ -450,7 +466,7 @@ export function test_parse_ShouldParseCustomComponentWithoutXmlInListViewTemplat
}
export function test_parse_ShouldParseNestedListViewInListViewTemplate() {
var p = <page.Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd"><ListView items="{{ items }}" itemLoading="{{ itemLoading }}"><ListView.itemTemplate><ListView items="{{ subItems }}" /></ListView.itemTemplate></ListView></Page>');
var p = <Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd"><ListView items="{{ items }}" itemLoading="{{ itemLoading }}"><ListView.itemTemplate><ListView items="{{ subItems }}" /></ListView.itemTemplate></ListView></Page>');
function testAction(views: Array<viewModule.View>) {
var ctrl;
@@ -492,15 +508,15 @@ export function test_parse_NestedRepeaters() {
" </Repeater.itemTemplate>" +
" </Repeater>" +
"</Page>";
var p = <page.Page>builder.parse(pageXML);
var p = <Page>builder.parse(pageXML);
function testAction(views: Array<viewModule.View>) {
p.bindingContext = [["0", "1"], ["2", "3"]];
TKUnit.wait(0.2);
var lbls = new Array<labelModule.Label>();
var lbls = new Array<Label>();
view.eachDescendant(p, (v) => {
if (v instanceof labelModule.Label) {
if (v instanceof Label) {
lbls.push(v);
}
return true;

View File

@@ -2,12 +2,12 @@ import view = require("ui/core/view");
import pages = require("ui/page");
export function applyTap(args) {
var page = <pages.Page>view.getAncestor(args.object, "Page");
var page = <pages.Page>(<view.View>args.object).page;
var css = "#test-element { " + args.object.tag + " }";
page.css = css;
}
export function resetTap(args) {
var page = <pages.Page>view.getAncestor(args.object, "Page");
var page = <pages.Page>(<view.View>args.object).page;
page.css = "";
}
}

View File

@@ -55,14 +55,21 @@ export function eachDescendant(view: definition.View, callback: (child: View) =>
view._eachChildView(localCallback);
}
export function getAncestor(view: View, typeName: string): definition.View {
var parent = view.parent;
while (parent && parent.typeName !== typeName) {
parent = parent.parent;
export function getAncestor(view: View, criterion: string | Function): definition.View {
let matcher: (view: definition.View) => boolean = null;
if (typeof criterion === "string") {
matcher = (view: definition.View) => view.typeName === criterion;
} else {
matcher = (view: definition.View) => view instanceof criterion;
}
return parent;
for (let parent: definition.View = view.parent; parent != null; parent = parent.parent) {
if (matcher(parent)) {
return parent;
}
}
return null;
}
var viewIdCounter = 0;
@@ -331,6 +338,14 @@ export class View extends proxy.ProxyObject implements definition.View {
this._setValue(View.isEnabledProperty, value);
}
get page(): definition.View {
if (this.parent) {
return this.parent.page;
}
return null;
}
get isUserInteractionEnabled(): boolean {
return this._getValue(View.isUserInteractionEnabledProperty);
}
@@ -710,7 +725,7 @@ export class View extends proxy.ProxyObject implements definition.View {
}
private _applyStyleFromScope() {
var rootPage = getAncestor(this, "Page");
var rootPage = this.page;
if (!rootPage || !rootPage.isLoaded) {
return;
}
@@ -933,4 +948,4 @@ export class View extends proxy.ProxyObject implements definition.View {
animation.target = that;
return new animationModule.Animation([animation]);
}
}
}

11
ui/core/view.d.ts vendored
View File

@@ -25,10 +25,10 @@ declare module "ui/core/view" {
/**
* Gets an ancestor from a given type.
* @param view - Starting view (child view).
* @param typeName - The type name of the parent container which is looking for.
* @param criterion - The type of ancestor view we are looking for. Could be a string containing a class name or an actual type.
* Returns an instance of a view (if found), otherwise undefined.
*/
export function getAncestor(view: View, typeName: string): View;
export function getAncestor(view: View, criterion: string | Function): View;
/**
* Defines interface for an optional parameter used to create a view.
@@ -258,7 +258,7 @@ declare module "ui/core/view" {
parent: View;
/**
* Gets is layout is valid. This is read-only property.
* Gets is layout is valid. This is a read-only property.
*/
isLayoutValid: boolean;
@@ -266,6 +266,11 @@ declare module "ui/core/view" {
visualState: string;
/**
* Gets owner page. This is a read-only property.
*/
page: View;
/**
* This is called to find out how big a view should be. The parent supplies constraint information in the width and height parameters.
* The actual measurement work of a view is performed in onMeasure(int, int), called by this method. Therefore, only onMeasure(int, int) can and must be overridden by subclasses.

View File

@@ -104,6 +104,10 @@ export class Page extends contentView.ContentView implements dts.Page {
}
}
get page(): view.View {
return this;
}
private _refreshCss(): void {
if (this._cssApplied) {
this._resetCssValues();
@@ -263,4 +267,4 @@ export class Page extends contentView.ContentView implements dts.Page {
return super._addViewToNativeVisualTree(view);
}
}
}

View File

@@ -19,7 +19,7 @@ export class VisualState {
*
*/
export function goToState(view: viewModule.View, state: string): string {
var root = <any>viewModule.getAncestor(view, "Page");
var root = <any>view.page;
if (!root) {
return undefined;
}
@@ -90,4 +90,4 @@ function applyProperties(view: viewModule.View, state: VisualState) {
view.style._setValue(property, state.setters[name], observable.ValueSource.VisualState);
}
}
}
}

View File

@@ -344,7 +344,7 @@ export class TabView extends common.TabView {
}
public _addTabs(newItems: Array<definition.TabViewItem>) {
var parentPage = <page.Page>view.getAncestor(this, "Page");
var parentPage = <page.Page>this.page;
if (parentPage && parentPage.actionBarHidden) {
return;
}
@@ -421,7 +421,7 @@ export class TabView extends common.TabView {
}
public _removeTabs(oldItems: Array<definition.TabViewItem>) {
var parentPage = <page.Page>view.getAncestor(this, "Page");
var parentPage = <page.Page>this.page;
if (parentPage && parentPage.actionBarHidden) {
return;
}
@@ -511,4 +511,4 @@ export class TabView extends common.TabView {
var activity = <android.app.Activity>this._android.getContext();
return activity.getActionBar();
}
}
}