Skip to content

Commit 75253f0

Browse files
author
Nedyalko Nikolov
committed
Merge pull request NativeScript#185 from NativeScript/nnikolov/BindingExpressionsFix
Fixed binding expression for object property access (not function).
2 parents 2cfaaca + e61cac3 commit 75253f0

File tree

4 files changed

+51
-27
lines changed

4 files changed

+51
-27
lines changed

apps/tests/ui/bindable-tests.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import bindingBuilder = require("ui/builder/binding-builder");
1313
import labelModule = require("ui/label");
1414
import textFieldModule = require("ui/text-field");
1515
import fs = require("file-system");
16+
import appModule = require("application");
1617

1718
// <snippet module="ui/core/bindable" title="bindable">
1819
// 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 () {
513514
TKUnit.assertEqual(testLabel.text, expectedValue);
514515
}
515516

517+
helper.buildUIAndRunTest(createLabel(), testFunc);
518+
}
519+
520+
export function test_BindingToDictionaryAtAppLevel() {
521+
var createLabel = function () {
522+
var label = new labelModule.Label();
523+
return label;
524+
}
525+
var pageViewModel = new observable.Observable();
526+
var testPropertyName = "testValue";
527+
var expectedValue = "expectedValue";
528+
pageViewModel.set("testProperty", testPropertyName);
529+
var dict = {};
530+
dict[testPropertyName] = expectedValue;
531+
appModule.resources["dict"] = dict;
532+
533+
var testFunc = function (views: Array<viewModule.View>) {
534+
var testLabel = <labelModule.Label>(views[0]);
535+
testLabel.bind({ sourceProperty: "testProperty", targetProperty: "text", expression: "dict[testProperty]" });
536+
537+
var page = <pageModule.Page>(views[1]);
538+
page.bindingContext = pageViewModel;
539+
540+
TKUnit.assertEqual(testLabel.text, expectedValue);
541+
}
542+
516543
helper.buildUIAndRunTest(createLabel(), testFunc);
517544
}

js-libs/polymer-expressions/polymer-expressions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ var Path = require("js-libs/polymer-expressions/path-parser").Path;
405405
getValue: function (model, isBackConvert, changedModel, observer) {
406406
var value = getFn(this.expression)(model.context, observer, changedModel);
407407
for (var i = 0; i < this.filters.length; i++) {
408-
value = this.filters[i].transform(model.context, observer, model.resources, isBackConvert, [value]);
408+
value = this.filters[i].transform(model.context, observer, model.context, isBackConvert, [value]);
409409
}
410410

411411
return value;

ui/builder/binding-builder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var expressionSymbolsRegex = /[ \+\-\*%\?:<>=!\|&\(\)\[\]]/;
1+
var expressionSymbolsRegex = /[ \+\-\*%\?:<>=!\|&\(\)\[\]^~]/;
22

33
export module bindingConstants {
44
export var sourceProperty = "sourceProperty";

ui/core/bindable.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ function onBindingContextChanged(data: dependencyObservable.PropertyChangeData)
2121
}
2222

2323
var contextKey = "context";
24-
var resourcesKey = "resources";
2524

2625
export class Bindable extends dependencyObservable.DependencyObservable implements definition.Bindable {
2726

@@ -203,13 +202,18 @@ export class Binding {
203202
return;
204203
}
205204
if (this.options.twoWay) {
206-
if (this._isExpression(this.options.expression)) {
205+
if (this.options.expression) {
207206
var changedModel = {};
208-
if (this.options.sourceProperty === bindingBuilder.bindingConstants.bindingValueKey) {
209-
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = value;
207+
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = value;
208+
var sourcePropertyName = "";
209+
if (this.sourceOptions) {
210+
sourcePropertyName = this.sourceOptions.property;
210211
}
211-
else {
212-
changedModel[this.options.sourceProperty] = value;
212+
else if (typeof this.options.sourceProperty === "string" && this.options.sourceProperty.indexOf(".") === -1) {
213+
sourcePropertyName = this.options.sourceProperty;
214+
}
215+
if (sourcePropertyName !== "") {
216+
changedModel[sourcePropertyName] = value;
213217
}
214218
var expressionValue = this._getExpressionValue(this.options.expression, true, changedModel);
215219
if (expressionValue instanceof Error) {
@@ -225,25 +229,20 @@ export class Binding {
225229
}
226230
}
227231

228-
private _isExpression(expression: string): boolean {
229-
if (expression) {
230-
var result = expression.indexOf(" ") !== -1;
231-
return result;
232-
}
233-
else {
234-
return false;
235-
}
236-
}
237-
238232
private _getExpressionValue(expression: string, isBackConvert: boolean, changedModel: any): any {
239233
try {
240234
var exp = polymerExpressions.PolymerExpressions.getExpression(expression);
241235
if (exp) {
242236
var context = this.source && this.source.get && this.source.get() || global;
243237
var model = {};
244-
model[contextKey] = context;
245-
model[resourcesKey] = appModule.resources;
246-
return exp.getValue(model, isBackConvert, changedModel);
238+
for (var prop in appModule.resources) {
239+
if (appModule.resources.hasOwnProperty(prop) && !context.hasOwnProperty(prop)) {
240+
context[prop] = appModule.resources[prop];
241+
}
242+
}
243+
244+
model[contextKey] = context;
245+
return exp.getValue(model, isBackConvert, changedModel);
247246
}
248247
return new Error(expression + " is not a valid expression.");
249248
}
@@ -254,7 +253,7 @@ export class Binding {
254253
}
255254

256255
public onSourcePropertyChanged(data: observable.PropertyChangeData) {
257-
if (this._isExpression(this.options.expression)) {
256+
if (this.options.expression) {
258257
var expressionValue = this._getExpressionValue(this.options.expression, false, undefined);
259258
if (expressionValue instanceof Error) {
260259
trace.write((<Error>expressionValue).message, trace.categories.Binding, trace.messageType.error);
@@ -268,11 +267,9 @@ export class Binding {
268267
}
269268

270269
private getSourceProperty() {
271-
if (this._isExpression(this.options.expression)) {
270+
if (this.options.expression) {
272271
var changedModel = {};
273-
if (this.options.sourceProperty === bindingBuilder.bindingConstants.bindingValueKey) {
274-
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = this.source.get();
275-
}
272+
changedModel[bindingBuilder.bindingConstants.bindingValueKey] = this.source.get();
276273
var expressionValue = this._getExpressionValue(this.options.expression, false, changedModel);
277274
if (expressionValue instanceof Error) {
278275
trace.write((<Error>expressionValue).message, trace.categories.Binding, trace.messageType.error);
@@ -339,7 +336,7 @@ export class Binding {
339336
return options;
340337
}
341338

342-
if (!this._isExpression(property) && types.isString(property) && property.indexOf(".") !== -1) {
339+
if (types.isString(property) && property.indexOf(".") !== -1) {
343340
var properties = property.split(".");
344341

345342
var i: number;

0 commit comments

Comments
 (0)