From a0156def3334c69125af9c2881e4ab6c6ecd9caa Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Wed, 24 Jun 2020 18:47:33 +0300 Subject: [PATCH 1/3] fix: #8666 #6981 #5054 --- e2e/ui-tests-app/app/list-view/main-page.ts | 1 + .../app/list-view/parents-expression-page.ts | 27 +++++++++++++ .../app/list-view/parents-expression-page.xml | 20 ++++++++++ .../ui/core/bindable/bindable.ts | 39 ++++++++++++++----- 4 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 e2e/ui-tests-app/app/list-view/parents-expression-page.ts create mode 100644 e2e/ui-tests-app/app/list-view/parents-expression-page.xml diff --git a/e2e/ui-tests-app/app/list-view/main-page.ts b/e2e/ui-tests-app/app/list-view/main-page.ts index 7138d51e3c..7689313b67 100644 --- a/e2e/ui-tests-app/app/list-view/main-page.ts +++ b/e2e/ui-tests-app/app/list-view/main-page.ts @@ -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; } diff --git a/e2e/ui-tests-app/app/list-view/parents-expression-page.ts b/e2e/ui-tests-app/app/list-view/parents-expression-page.ts new file mode 100644 index 0000000000..bb7f2ef5b3 --- /dev/null +++ b/e2e/ui-tests-app/app/list-view/parents-expression-page.ts @@ -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" + } + ] + }); +} diff --git a/e2e/ui-tests-app/app/list-view/parents-expression-page.xml b/e2e/ui-tests-app/app/list-view/parents-expression-page.xml new file mode 100644 index 0000000000..79aab83efb --- /dev/null +++ b/e2e/ui-tests-app/app/list-view/parents-expression-page.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/nativescript-core/ui/core/bindable/bindable.ts b/nativescript-core/ui/core/bindable/bindable.ts index 46428f254c..0ce92d63b2 100644 --- a/nativescript-core/ui/core/bindable/bindable.ts +++ b/nativescript-core/ui/core/bindable/bindable.ts @@ -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() { From eba426c09ec3cc437f968d6f23a643a557383a27 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Wed, 24 Jun 2020 19:06:27 +0300 Subject: [PATCH 2/3] Fixed indentation issues. --- e2e/ui-tests-app/app/list-view/parents-expression-page.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/ui-tests-app/app/list-view/parents-expression-page.ts b/e2e/ui-tests-app/app/list-view/parents-expression-page.ts index bb7f2ef5b3..a060e894d6 100644 --- a/e2e/ui-tests-app/app/list-view/parents-expression-page.ts +++ b/e2e/ui-tests-app/app/list-view/parents-expression-page.ts @@ -3,10 +3,10 @@ import { fromObject } from "tns-core-modules/data/observable"; export function onLoaded(args) { const page = args.object; - page.bindingContext = fromObject( + page.bindingContext = fromObject( { - prefix: "This is a prefix for: ", - languageData: [ + prefix: "This is a prefix for: ", + languageData: [ { name: "English", }, From b02fa2226847893f62994792b004da462e71dad4 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Wed, 24 Jun 2020 19:21:12 +0300 Subject: [PATCH 3/3] Indentation issues. --- .../app/list-view/parents-expression-page.ts | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/e2e/ui-tests-app/app/list-view/parents-expression-page.ts b/e2e/ui-tests-app/app/list-view/parents-expression-page.ts index a060e894d6..fe060077b4 100644 --- a/e2e/ui-tests-app/app/list-view/parents-expression-page.ts +++ b/e2e/ui-tests-app/app/list-view/parents-expression-page.ts @@ -3,25 +3,25 @@ import { fromObject } from "tns-core-modules/data/observable"; export function onLoaded(args) { const page = args.object; - page.bindingContext = fromObject( + page.bindingContext = fromObject( { - prefix: "This is a prefix for: ", - languageData: [ - { - name: "English", - }, - { - name: "Portuguese" - }, - { - name: "Spanish" - }, - { - name: "Russian" - }, - { - name: "Greek" - } - ] - }); + prefix: "This is a prefix for: ", + languageData: [ + { + name: "English", + }, + { + name: "Portuguese" + }, + { + name: "Spanish" + }, + { + name: "Russian" + }, + { + name: "Greek" + } + ] + }); }