mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 20:11:24 +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);
|
}, bindingSource);
|
||||||
|
|
||||||
TKUnit.assertEqual(testElement.get("targetPropertyName"), "testValue");
|
TKUnit.assertEqual(testElement.get("targetPropertyName"), "testValue");
|
||||||
|
TKUnit.assertTrue(bindingSource['$value'] === undefined, "We should not add $value to bindingSource.");
|
||||||
}
|
}
|
||||||
|
|
||||||
export var test_TwoElementsBindingToSameBindingContext = function () {
|
export var test_TwoElementsBindingToSameBindingContext = function () {
|
||||||
@ -546,6 +547,58 @@ export var test_BindingToSource_FailsAfterBindingContextChange = function () {
|
|||||||
helper.buildUIAndRunTest(createLabel(), testFunc);
|
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() {
|
export function test_BindingToDictionaryAtAppLevel() {
|
||||||
var createLabel = function () {
|
var createLabel = function () {
|
||||||
var label = new labelModule.Label();
|
var label = new labelModule.Label();
|
||||||
@ -998,6 +1051,7 @@ export function test_$ValueSupportWithinExpression() {
|
|||||||
model.set("anyColor", "red");
|
model.set("anyColor", "red");
|
||||||
|
|
||||||
TKUnit.assertEqual(bindableObj.get("test"), "red", "When anyColor is red test property should be red too.");
|
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 {
|
class DummyNestedClass extends observable.Observable {
|
||||||
|
@ -330,7 +330,7 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let updateExpression = this.prepareExpressionForUpdate();
|
let updateExpression = this.prepareExpressionForUpdate();
|
||||||
this.prepareContextForExpression(changedModel, updateExpression);
|
this.prepareContextForExpression(changedModel, updateExpression, undefined);
|
||||||
|
|
||||||
let expressionValue = this._getExpressionValue(updateExpression, true, changedModel);
|
let expressionValue = this._getExpressionValue(updateExpression, true, changedModel);
|
||||||
if (expressionValue instanceof Error) {
|
if (expressionValue instanceof Error) {
|
||||||
@ -357,7 +357,7 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.prepareContextForExpression(context, expression);
|
this.prepareContextForExpression(context, expression, addedProps);
|
||||||
model[contextKey] = context;
|
model[contextKey] = context;
|
||||||
let result = exp.getValue(model, isBackConvert, changedModel ? changedModel : model);
|
let result = exp.getValue(model, isBackConvert, changedModel ? changedModel : model);
|
||||||
// clear added props
|
// 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 parentViewAndIndex: { view: viewModule.View, index: number };
|
||||||
let parentView;
|
let parentView;
|
||||||
|
let addedProps = newProps || [];
|
||||||
if (expression.indexOf(bc.bindingValueKey) > -1) {
|
if (expression.indexOf(bc.bindingValueKey) > -1) {
|
||||||
model[bc.bindingValueKey] = model;
|
model[bc.bindingValueKey] = model;
|
||||||
|
addedProps.push(bc.bindingValueKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression.indexOf(bc.parentValueKey) > -1) {
|
if (expression.indexOf(bc.parentValueKey) > -1) {
|
||||||
parentView = this.getParentView(this.target.get(), bc.parentValueKey).view;
|
parentView = this.getParentView(this.target.get(), bc.parentValueKey).view;
|
||||||
if (parentView) {
|
if (parentView) {
|
||||||
model[bc.parentValueKey] = parentView.bindingContext;
|
model[bc.parentValueKey] = parentView.bindingContext;
|
||||||
|
addedProps.push(bc.parentValueKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,6 +467,7 @@ export class Binding {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user