Skip to content
Merged
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
1 change: 1 addition & 0 deletions e2e/ui-tests-app/app/list-view/main-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export function loadExamples() {
examples.set("width-percent", "list-view/width-percent-page");
examples.set("item-re-layout", "list-view/item-re-layout-page");
examples.set("safe-area", "list-view/safe-area-page");
examples.set("parents-expression", "list-view/parents-expression-page");

return examples;
}
27 changes: 27 additions & 0 deletions e2e/ui-tests-app/app/list-view/parents-expression-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { fromObject } from "tns-core-modules/data/observable";

export function onLoaded(args)
{
const page = args.object;
page.bindingContext = fromObject(
{
prefix: "This is a prefix for: ",
languageData: [
{
name: "English",
},
{
name: "Portuguese"
},
{
name: "Spanish"
},
{
name: "Russian"
},
{
name: "Greek"
}
]
});
}
20 changes: 20 additions & 0 deletions e2e/ui-tests-app/app/list-view/parents-expression-page.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onLoaded" class="page">

<Page.actionBar>
<ActionBar title="My App" icon="" class="action-bar">
</ActionBar>
</Page.actionBar>

<ListView items="{{ languageData }}" separatorColor="red">
<ListView.itemTemplate>
<StackLayout columns="*,40" rows="*,*">
<!-- It works if not an expression -->
<Label row="1" text="{{ $parents['Page'].prefix }}"
class="font-weight-bold" fontSize="16" />
<!-- Until component gets loaded, $parents['Page'].prefix will return undefined -->
<Label row="1" text="{{ $parents['Page'].prefix + name }}"
class="font-weight-bold" fontSize="16" />
</StackLayout>
</ListView.itemTemplate>
</ListView>
</Page>
39 changes: 30 additions & 9 deletions nativescript-core/ui/core/bindable/bindable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,30 +469,51 @@ export class Binding {
let parentViewAndIndex: { view: ViewBase, index: number };
let parentView;
let addedProps = newProps || [];
if (expression.indexOf(bc.bindingValueKey) > -1) {
let expressionCP = expression;
if (expressionCP.indexOf(bc.bindingValueKey) > -1) {
model[bc.bindingValueKey] = model;
addedProps.push(bc.bindingValueKey);
}

if (expression.indexOf(bc.parentValueKey) > -1) {
parentView = this.getParentView(this.target.get(), bc.parentValueKey).view;
if (parentView) {
model[bc.parentValueKey] = parentView.bindingContext;
addedProps.push(bc.parentValueKey);
}
}
let success: boolean = true;

let parentsArray = expression.match(parentsRegex);
let parentsArray = expressionCP.match(parentsRegex);
if (parentsArray) {
for (let i = 0; i < parentsArray.length; i++) {
// This prevents later checks to mistake $parents[] for $parent
expressionCP = expressionCP.replace(parentsArray[i], "");
parentViewAndIndex = this.getParentView(this.target.get(), parentsArray[i]);
if (parentViewAndIndex.view) {
model[bc.parentsValueKey] = model[bc.parentsValueKey] || {};
model[bc.parentsValueKey][parentViewAndIndex.index] = parentViewAndIndex.view.bindingContext;
addedProps.push(bc.parentsValueKey);
}
else
{
success = false;
}
}
}

if (expressionCP.indexOf(bc.parentValueKey) > -1) {
parentView = this.getParentView(this.target.get(), bc.parentValueKey).view;
if (parentView) {
model[bc.parentValueKey] = parentView.bindingContext;
addedProps.push(bc.parentValueKey);
}
else
{
success = false;
}
}

// For expressions, there are also cases when binding must be updated after component is loaded (e.g. ListView)
if (!success)
{
let targetInstance = this.target.get();
targetInstance.off("loaded", this.loadedHandlerVisualTreeBinding, this);
targetInstance.on("loaded", this.loadedHandlerVisualTreeBinding, this);
}
}

private getSourcePropertyValue() {
Expand Down