mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 19:26:42 +08:00
fix(bindable): parent referenced expression-values now load properly using an update call (#8670)
closes #8666 closes #6981 closes #5054
This commit is contained in:
@ -22,6 +22,7 @@ export function loadExamples() {
|
|||||||
examples.set("width-percent", "list-view/width-percent-page");
|
examples.set("width-percent", "list-view/width-percent-page");
|
||||||
examples.set("item-re-layout", "list-view/item-re-layout-page");
|
examples.set("item-re-layout", "list-view/item-re-layout-page");
|
||||||
examples.set("safe-area", "list-view/safe-area-page");
|
examples.set("safe-area", "list-view/safe-area-page");
|
||||||
|
examples.set("parents-expression", "list-view/parents-expression-page");
|
||||||
|
|
||||||
return examples;
|
return examples;
|
||||||
}
|
}
|
||||||
|
27
e2e/ui-tests-app/app/list-view/parents-expression-page.ts
Normal file
27
e2e/ui-tests-app/app/list-view/parents-expression-page.ts
Normal file
@ -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
e2e/ui-tests-app/app/list-view/parents-expression-page.xml
Normal file
20
e2e/ui-tests-app/app/list-view/parents-expression-page.xml
Normal file
@ -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>
|
@ -469,32 +469,53 @@ export class Binding {
|
|||||||
let parentViewAndIndex: { view: ViewBase, index: number };
|
let parentViewAndIndex: { view: ViewBase, index: number };
|
||||||
let parentView;
|
let parentView;
|
||||||
let addedProps = newProps || [];
|
let addedProps = newProps || [];
|
||||||
if (expression.indexOf(bc.bindingValueKey) > -1) {
|
let expressionCP = expression;
|
||||||
|
if (expressionCP.indexOf(bc.bindingValueKey) > -1) {
|
||||||
model[bc.bindingValueKey] = model;
|
model[bc.bindingValueKey] = model;
|
||||||
addedProps.push(bc.bindingValueKey);
|
addedProps.push(bc.bindingValueKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression.indexOf(bc.parentValueKey) > -1) {
|
let success: boolean = true;
|
||||||
parentView = this.getParentView(this.target.get(), bc.parentValueKey).view;
|
|
||||||
if (parentView) {
|
|
||||||
model[bc.parentValueKey] = parentView.bindingContext;
|
|
||||||
addedProps.push(bc.parentValueKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let parentsArray = expression.match(parentsRegex);
|
let parentsArray = expressionCP.match(parentsRegex);
|
||||||
if (parentsArray) {
|
if (parentsArray) {
|
||||||
for (let i = 0; i < parentsArray.length; i++) {
|
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]);
|
parentViewAndIndex = this.getParentView(this.target.get(), parentsArray[i]);
|
||||||
if (parentViewAndIndex.view) {
|
if (parentViewAndIndex.view) {
|
||||||
model[bc.parentsValueKey] = model[bc.parentsValueKey] || {};
|
model[bc.parentsValueKey] = model[bc.parentsValueKey] || {};
|
||||||
model[bc.parentsValueKey][parentViewAndIndex.index] = parentViewAndIndex.view.bindingContext;
|
model[bc.parentsValueKey][parentViewAndIndex.index] = parentViewAndIndex.view.bindingContext;
|
||||||
addedProps.push(bc.parentsValueKey);
|
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() {
|
private getSourcePropertyValue() {
|
||||||
if (this.options.expression) {
|
if (this.options.expression) {
|
||||||
let changedModel = {};
|
let changedModel = {};
|
||||||
|
Reference in New Issue
Block a user