Fixed binding expression for object property access (not function).

This commit is contained in:
Nedyalko Nikolov
2015-05-19 10:46:08 +03:00
parent 2cfaacac0e
commit e61cac3422
4 changed files with 51 additions and 27 deletions

View File

@ -13,6 +13,7 @@ import bindingBuilder = require("ui/builder/binding-builder");
import labelModule = require("ui/label");
import textFieldModule = require("ui/text-field");
import fs = require("file-system");
import appModule = require("application");
// <snippet module="ui/core/bindable" title="bindable">
// For information and examples how to use bindings please refer to special [**Data binding**](../../../../bindings.md) topic.
@ -513,5 +514,31 @@ export var test_BindingToSource_FailsAfterBindingContextChange = function () {
TKUnit.assertEqual(testLabel.text, expectedValue);
}
helper.buildUIAndRunTest(createLabel(), testFunc);
}
export function test_BindingToDictionaryAtAppLevel() {
var createLabel = function () {
var label = new labelModule.Label();
return label;
}
var pageViewModel = new observable.Observable();
var testPropertyName = "testValue";
var expectedValue = "expectedValue";
pageViewModel.set("testProperty", testPropertyName);
var dict = {};
dict[testPropertyName] = expectedValue;
appModule.resources["dict"] = dict;
var testFunc = function (views: Array<viewModule.View>) {
var testLabel = <labelModule.Label>(views[0]);
testLabel.bind({ sourceProperty: "testProperty", targetProperty: "text", expression: "dict[testProperty]" });
var page = <pageModule.Page>(views[1]);
page.bindingContext = pageViewModel;
TKUnit.assertEqual(testLabel.text, expectedValue);
}
helper.buildUIAndRunTest(createLabel(), testFunc);
}

View File

@ -405,7 +405,7 @@ var Path = require("js-libs/polymer-expressions/path-parser").Path;
getValue: function (model, isBackConvert, changedModel, observer) {
var value = getFn(this.expression)(model.context, observer, changedModel);
for (var i = 0; i < this.filters.length; i++) {
value = this.filters[i].transform(model.context, observer, model.resources, isBackConvert, [value]);
value = this.filters[i].transform(model.context, observer, model.context, isBackConvert, [value]);
}
return value;

View File

@ -1,4 +1,4 @@
var expressionSymbolsRegex = /[ \+\-\*%\?:<>=!\|&\(\)\[\]]/;
var expressionSymbolsRegex = /[ \+\-\*%\?:<>=!\|&\(\)\[\]^~]/;
export module bindingConstants {
export var sourceProperty = "sourceProperty";

View File

@ -21,7 +21,6 @@ function onBindingContextChanged(data: dependencyObservable.PropertyChangeData)
}
var contextKey = "context";
var resourcesKey = "resources";
export class Bindable extends dependencyObservable.DependencyObservable implements definition.Bindable {
@ -203,13 +202,18 @@ export class Binding {
return;
}
if (this.options.twoWay) {
if (this._isExpression(this.options.expression)) {
if (this.options.expression) {
var changedModel = {};
if (this.options.sourceProperty === bindingBuilder.bindingConstants.bindingValueKey) {
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = value;
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = value;
var sourcePropertyName = "";
if (this.sourceOptions) {
sourcePropertyName = this.sourceOptions.property;
}
else {
changedModel[this.options.sourceProperty] = value;
else if (typeof this.options.sourceProperty === "string" && this.options.sourceProperty.indexOf(".") === -1) {
sourcePropertyName = this.options.sourceProperty;
}
if (sourcePropertyName !== "") {
changedModel[sourcePropertyName] = value;
}
var expressionValue = this._getExpressionValue(this.options.expression, true, changedModel);
if (expressionValue instanceof Error) {
@ -225,25 +229,20 @@ export class Binding {
}
}
private _isExpression(expression: string): boolean {
if (expression) {
var result = expression.indexOf(" ") !== -1;
return result;
}
else {
return false;
}
}
private _getExpressionValue(expression: string, isBackConvert: boolean, changedModel: any): any {
try {
var exp = polymerExpressions.PolymerExpressions.getExpression(expression);
if (exp) {
var context = this.source && this.source.get && this.source.get() || global;
var model = {};
model[contextKey] = context;
model[resourcesKey] = appModule.resources;
return exp.getValue(model, isBackConvert, changedModel);
for (var prop in appModule.resources) {
if (appModule.resources.hasOwnProperty(prop) && !context.hasOwnProperty(prop)) {
context[prop] = appModule.resources[prop];
}
}
model[contextKey] = context;
return exp.getValue(model, isBackConvert, changedModel);
}
return new Error(expression + " is not a valid expression.");
}
@ -254,7 +253,7 @@ export class Binding {
}
public onSourcePropertyChanged(data: observable.PropertyChangeData) {
if (this._isExpression(this.options.expression)) {
if (this.options.expression) {
var expressionValue = this._getExpressionValue(this.options.expression, false, undefined);
if (expressionValue instanceof Error) {
trace.write((<Error>expressionValue).message, trace.categories.Binding, trace.messageType.error);
@ -268,11 +267,9 @@ export class Binding {
}
private getSourceProperty() {
if (this._isExpression(this.options.expression)) {
if (this.options.expression) {
var changedModel = {};
if (this.options.sourceProperty === bindingBuilder.bindingConstants.bindingValueKey) {
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = this.source.get();
}
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = this.source.get();
var expressionValue = this._getExpressionValue(this.options.expression, false, changedModel);
if (expressionValue instanceof Error) {
trace.write((<Error>expressionValue).message, trace.categories.Binding, trace.messageType.error);
@ -339,7 +336,7 @@ export class Binding {
return options;
}
if (!this._isExpression(property) && types.isString(property) && property.indexOf(".") !== -1) {
if (types.isString(property) && property.indexOf(".") !== -1) {
var properties = property.split(".");
var i: number;