mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
Merge pull request #2064 from NativeScript/nnikolov/BindingChangingContextFix
Additional fix for changing binding context issue.
This commit is contained in:
@ -492,6 +492,7 @@ export var test_bindingToNestedPropertyWithValueSyntax = function () {
|
||||
}, bindingSource);
|
||||
|
||||
TKUnit.assertEqual(testElement.get("targetPropertyName"), "testValue");
|
||||
TKUnit.assertTrue(bindingSource['$value'] === undefined, "We should not add $value to bindingSource.");
|
||||
}
|
||||
|
||||
export var test_TwoElementsBindingToSameBindingContext = function () {
|
||||
@ -546,6 +547,58 @@ export var test_BindingToSource_FailsAfterBindingContextChange = function () {
|
||||
helper.buildUIAndRunTest(createLabel(), testFunc);
|
||||
}
|
||||
|
||||
export var test_BindingToParentView_ShouldNotLeaveGarbageInViewModel = function () {
|
||||
var createStack = function () {
|
||||
var stack = new stackLayoutModule.StackLayout();
|
||||
var label = new labelModule.Label();
|
||||
stack.addChild(label);
|
||||
return stack;
|
||||
}
|
||||
var stackViewModel = new observable.Observable();
|
||||
var expectedValue = "testValue";
|
||||
stackViewModel.set("testProperty", expectedValue);
|
||||
|
||||
var testFunc = function (views: Array<viewModule.View>) {
|
||||
let testStack = <stackLayoutModule.StackLayout>(views[0]);
|
||||
testStack.bindingContext = stackViewModel;
|
||||
|
||||
let testLabel = <labelModule.Label>(testStack.getChildAt(0));
|
||||
testLabel.bind({ sourceProperty: "$parent.testProperty", targetProperty: "text", expression: "$parent.testProperty"});
|
||||
|
||||
TKUnit.assertEqual(testLabel.text, expectedValue);
|
||||
TKUnit.assertTrue(stackViewModel['$parent'] === undefined, "stackViewModel['$parent'] should be removed from parent binding context.");
|
||||
TKUnit.assertTrue(testLabel.bindingContext['$parent'] === undefined, "testLabel.bindingContext['$parent'] should be removed from parent binding context.");
|
||||
}
|
||||
|
||||
helper.buildUIAndRunTest(createStack(), testFunc);
|
||||
}
|
||||
|
||||
export var test_BindingToParentsView_ShouldNotLeaveGarbageInViewModel = function () {
|
||||
var createStack = function () {
|
||||
var stack = new stackLayoutModule.StackLayout();
|
||||
var label = new labelModule.Label();
|
||||
stack.addChild(label);
|
||||
return stack;
|
||||
}
|
||||
var stackViewModel = new observable.Observable();
|
||||
var expectedValue = "testValue";
|
||||
stackViewModel.set("testProperty", expectedValue);
|
||||
|
||||
var testFunc = function (views: Array<viewModule.View>) {
|
||||
let testStack = <stackLayoutModule.StackLayout>(views[0]);
|
||||
testStack.bindingContext = stackViewModel;
|
||||
|
||||
let testLabel = <labelModule.Label>(testStack.getChildAt(0));
|
||||
testLabel.bind({ sourceProperty: "$parents['StackLayout'].testProperty", targetProperty: "text", expression: "$parents['StackLayout'].testProperty"});
|
||||
|
||||
TKUnit.assertEqual(testLabel.text, expectedValue);
|
||||
TKUnit.assertTrue(stackViewModel['$parent'] === undefined, "stackViewModel['$parent'] should be removed from parent binding context.");
|
||||
TKUnit.assertTrue(testLabel.bindingContext['$parents'] === undefined, "testLabel.bindingContext['$parents'] should be removed from parent binding context.");
|
||||
}
|
||||
|
||||
helper.buildUIAndRunTest(createStack(), testFunc);
|
||||
}
|
||||
|
||||
export function test_BindingToDictionaryAtAppLevel() {
|
||||
var createLabel = function () {
|
||||
var label = new labelModule.Label();
|
||||
@ -998,6 +1051,7 @@ export function test_$ValueSupportWithinExpression() {
|
||||
model.set("anyColor", "red");
|
||||
|
||||
TKUnit.assertEqual(bindableObj.get("test"), "red", "When anyColor is red test property should be red too.");
|
||||
TKUnit.assertTrue(model['$value'] === undefined, "We should not add $value to binding context.");
|
||||
}
|
||||
|
||||
class DummyNestedClass extends observable.Observable {
|
||||
|
@ -330,7 +330,7 @@ export class Binding {
|
||||
}
|
||||
|
||||
let updateExpression = this.prepareExpressionForUpdate();
|
||||
this.prepareContextForExpression(changedModel, updateExpression);
|
||||
this.prepareContextForExpression(changedModel, updateExpression, undefined);
|
||||
|
||||
let expressionValue = this._getExpressionValue(updateExpression, true, changedModel);
|
||||
if (expressionValue instanceof Error) {
|
||||
@ -357,7 +357,7 @@ export class Binding {
|
||||
}
|
||||
}
|
||||
|
||||
this.prepareContextForExpression(context, expression);
|
||||
this.prepareContextForExpression(context, expression, addedProps);
|
||||
model[contextKey] = context;
|
||||
let result = exp.getValue(model, isBackConvert, changedModel ? changedModel : model);
|
||||
// clear added props
|
||||
@ -443,17 +443,20 @@ export class Binding {
|
||||
}
|
||||
}
|
||||
|
||||
private prepareContextForExpression(model: Object, expression: string) {
|
||||
private prepareContextForExpression(model: Object, expression: string, newProps: Array<string>) {
|
||||
let parentViewAndIndex: { view: viewModule.View, index: number };
|
||||
let parentView;
|
||||
let addedProps = newProps || [];
|
||||
if (expression.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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -464,6 +467,7 @@ export class Binding {
|
||||
if (parentViewAndIndex.view) {
|
||||
model[bc.parentsValueKey] = model[bc.parentsValueKey] || {};
|
||||
model[bc.parentsValueKey][parentViewAndIndex.index] = parentViewAndIndex.view.bindingContext;
|
||||
addedProps.push(bc.parentsValueKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user