mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
Observable array now fires property change for length property.
This commit is contained in:
@ -1,24 +1,32 @@
|
||||
import pageModule = require("ui/page");
|
||||
//import stackLayoutModule = require("ui/layouts/stack-layout");
|
||||
//import textFieldModule = require("ui/text-field");
|
||||
import buttonModule = require("ui/button");
|
||||
import observableModule = require("data/observable");
|
||||
import observableArray = require("data/observable-array");
|
||||
import bindableModule = require("ui/core/bindable");
|
||||
//import enums = require("ui/enums");
|
||||
import trace = require("trace");
|
||||
trace.setCategories(trace.categories.Test);
|
||||
trace.setCategories(trace.categories.Test + "," + trace.categories.Binding);
|
||||
trace.enable();
|
||||
|
||||
export function pageLoaded(args: observableModule.EventData) {
|
||||
var page: pageModule.Page = <pageModule.Page>args.object;
|
||||
var model = new observableModule.Observable();
|
||||
var tasks = new observableArray.ObservableArray();
|
||||
//tasks.push("tralala");
|
||||
//var model = page.bindingContext;
|
||||
model.set("tasks", tasks);
|
||||
model.set("paramProperty", "%%%");
|
||||
var toUpperConverter: bindableModule.ValueConverter = {
|
||||
toModel: function (value, param1) {
|
||||
return param1 + value.toLowerCase();
|
||||
},
|
||||
toView: function (value, param1) {
|
||||
return value.toUpperCase();
|
||||
if (value === 0) {
|
||||
return "no items";
|
||||
}
|
||||
return value + " items";
|
||||
}
|
||||
};
|
||||
model.set("toUpper", toUpperConverter);
|
||||
@ -27,6 +35,12 @@ export function pageLoaded(args: observableModule.EventData) {
|
||||
page.bindingContext = model;
|
||||
}
|
||||
|
||||
export function onTap(args: observableModule.EventData) {
|
||||
var button: buttonModule.Button = <buttonModule.Button>args.object;
|
||||
trace.write("tasks: " + button.bindingContext.get("tasks"), trace.categories.Test, trace.messageType.info);
|
||||
button.bindingContext.get("tasks").push("alabala");
|
||||
}
|
||||
|
||||
//export function createPage() {
|
||||
// var stackLayout = new stackLayoutModule.StackLayout();
|
||||
// var firstTextField = new textFieldModule.TextField();
|
||||
|
@ -1,7 +1,6 @@
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
|
||||
<StackLayout padding="7">
|
||||
<TextField text="{{ testProperty, testProperty | toUpper(paramProperty) }}" />
|
||||
<!--<TextField text="{{ testProperty | toUpper }}" />-->
|
||||
<TextField text="{{ testProperty }}" />
|
||||
<TextField text="{{ tasks.length, tasks.length === 0 ? 'zero items' : tasks.length + ' items', false }}" />
|
||||
<Button text="Click" tap="onTap" />
|
||||
</StackLayout>
|
||||
</Page>
|
@ -1,4 +1,5 @@
|
||||
import TKUnit = require("./TKUnit");
|
||||
import bindableModule = require("ui/core/bindable");
|
||||
require("globals");
|
||||
|
||||
// <snippet module="data/observable-array" title="observable-array">
|
||||
@ -80,34 +81,6 @@ export var test_ObservableArray_concatShouldReturnNewArrayWithNewItemsAtTheEnd =
|
||||
TKUnit.assert(result.length === 6 && result[4] === 5, "ObservableArray concat() should add items at the end!");
|
||||
};
|
||||
|
||||
export var test_ObservableArray_concatShouldReturnNewArrayWithNewItemsAtTheEndAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
var result: observableArrayModule.ChangedData<number>;
|
||||
// <snippet module="data/observable-array" title="observable-array">
|
||||
// ### Use concat() method to append array to ObservableArray and handle "change" event.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
|
||||
array.on(observableArrayModule.knownEvents.change, (args: observableArrayModule.ChangedData<number>) => {
|
||||
//// Argument (args) is ChangedData<T>.
|
||||
//// args.eventName is "change".
|
||||
//// args.action is "add".
|
||||
//// args.index is equal to the array length.
|
||||
//// args.removed.length is 0.
|
||||
//// args.addedCount is equal to number of added items.
|
||||
|
||||
// <hide>
|
||||
result = args;
|
||||
// </hide>
|
||||
});
|
||||
|
||||
array.concat([4, 5, 6]);
|
||||
// ```
|
||||
// </snippet>
|
||||
|
||||
TKUnit.assert(result.eventName === "change" && result.action === observableArrayModule.ChangeType.Add &&
|
||||
result.removed.length === 0 && result.index === 3 && result.addedCount === 3, "ObservableArray concat() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export var test_ObservableArray_joinShouldReturnStringWithAllItemsSeparatedWithComma = function () {
|
||||
// <snippet module="data/observable-array" title="observable-array">
|
||||
// ### Use join() method to convert ObservableArray to comma separated string.
|
||||
@ -135,10 +108,16 @@ export var test_ObservableArray_popShouldRemoveTheLastElement = function () {
|
||||
// ### Use pop() method to remove the last element.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.pop();
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assert(result === 3 && array.length === 2, "ObservableArray pop() should remove last element!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_popShouldRemoveTheLastElementAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
@ -176,10 +155,16 @@ export var test_ObservableArray_pushShouldAppendNewElement = function () {
|
||||
// ### Use push() method to add single element to the array.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.push(4);
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assert(result === 4 && array.getItem(3) === 4, "ObservableArray push() should append new element!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_pushShouldAppendNewElementAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
@ -215,10 +200,16 @@ export var test_ObservableArray_pushShouldAppendNewElements = function () {
|
||||
// ### Use push() method to add multiple elements to the array.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.push(4, 5, 6);
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assert(result === 6 && array.getItem(5) === 6, "ObservableArray push() should append new elements!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_pushShouldAppendNewElementsAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
@ -254,10 +245,16 @@ export var test_ObservableArray_pushShouldAppendNewElementsFromSourceArray = fun
|
||||
// ### Use push() method to add multiple elements from source array to the ObservableArray.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.push([4, 5, 6]);
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assert(result === 6 && array.getItem(5) === 6, "ObservableArray push() should append new elements from source array!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_pushShouldAppendNewElementsFromSourceArrayAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
@ -304,10 +301,16 @@ export var test_ObservableArray_shiftShouldRemoveTheFirstElement = function () {
|
||||
// ### Use shift() method to remove the first element of the array.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.shift();
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assert(result === 1 && array.length === 2, "ObservableArray shift() should remove first element!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_shiftShouldRemoveTheFirstElementAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
@ -388,11 +391,17 @@ export var test_ObservableArray_spliceShouldRemoveSpecifiedNumberOfElementsStart
|
||||
// ### Use splice(start, deleteCount) method to delete elements in the array.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray(["one", "two", "three"]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.splice(1, 2);
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assert(result.length === 2 && result[0] === "two" && array.length === 1 && array.getItem(0) === "one",
|
||||
"ObservableArray splice() should remove specified number of elements starting from specified index!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_spliceShouldRemoveSpecifiedNumberOfElementsStartingFromSpecifiedIndexAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
@ -470,11 +479,17 @@ export var test_ObservableArray_unshiftShouldInsertNewElementsFromTheStart = fun
|
||||
// ### Use unshift(item1, item2... itemN) method to insert elements from the start of the array.
|
||||
// ``` JavaScript
|
||||
var array = new observableArrayModule.ObservableArray([1, 2, 3]);
|
||||
// <hide>
|
||||
var bindable = new bindableModule.Bindable();
|
||||
bindable.set("testProperty", 0);
|
||||
bindable.bind({ sourceProperty: "length", targetProperty: "testProperty" }, array);
|
||||
// </hide>
|
||||
var result = array.unshift(4, 5);
|
||||
// ```
|
||||
// </snippet>
|
||||
|
||||
TKUnit.assert(array.getItem(0) === 4 && result === 5 && array.length === 5, "ObservableArray unshift() should insert new elements from the start!");
|
||||
TKUnit.assert(bindable.get("testProperty") === array.length, "Expected: " + array.length + ", Actual: " + bindable.get("testProperty"));
|
||||
};
|
||||
|
||||
export var test_ObservableArray_unshiftShouldInsertNewElementsFromTheStartAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
|
@ -380,3 +380,43 @@ export var test_Bindable_BindingContext_String_DoesNotThrow = function () {
|
||||
|
||||
TKUnit.assert(obj.get("test") === 6, "Expected: 6; Actual: " + obj.get("test"));
|
||||
}
|
||||
|
||||
export var test_getBindableOptionsFromStringFullFormat = function () {
|
||||
var bindingExpression = "bindProperty, bindProperty * 2, false";
|
||||
var bindOptions = bindable.Bindable._getBindingOptions("targetBindProperty", bindingExpression);
|
||||
|
||||
TKUnit.assert(bindOptions.sourceProperty === "bindProperty", "Expected: bindProperty, Actual: " + bindOptions.sourceProperty);
|
||||
TKUnit.assert(bindOptions.targetProperty === "targetBindProperty", "Expected: targetBindProperty, Actual: " + bindOptions.targetProperty);
|
||||
TKUnit.assert(bindOptions.expression === "bindProperty * 2", "Expected: bindProperty * 2, Actual:" + bindOptions.expression);
|
||||
TKUnit.assert(bindOptions.twoWay === false, "Expected: false, Actual: " + bindOptions.twoWay);
|
||||
}
|
||||
|
||||
export var test_getBindableOptionsFromStringShortFormatExpression = function () {
|
||||
var bindingExpression = "bindProperty * 2";
|
||||
var bindOptions = bindable.Bindable._getBindingOptions("targetBindProperty", bindingExpression);
|
||||
|
||||
TKUnit.assert(bindOptions.sourceProperty === "bindProperty", "Expected: bindProperty, Actual: " + bindOptions.sourceProperty);
|
||||
TKUnit.assert(bindOptions.targetProperty === "targetBindProperty", "Expected: targetBindProperty, Actual: " + bindOptions.targetProperty);
|
||||
TKUnit.assert(bindOptions.expression === "bindProperty * 2", "Expected: bindProperty * 2, Actual: " + bindOptions.expression);
|
||||
TKUnit.assert(bindOptions.twoWay === true, "Expected: true, Actual: " + bindOptions.twoWay);
|
||||
}
|
||||
|
||||
export var test_getBindableOptionsFromStringShortFormatProperty = function () {
|
||||
var bindingExpression = "bindProperty";
|
||||
var bindOptions = bindable.Bindable._getBindingOptions("targetBindProperty", bindingExpression);
|
||||
|
||||
TKUnit.assert(bindOptions.sourceProperty === "bindProperty", "Expected: bindProperty, Actual: " + bindOptions.sourceProperty);
|
||||
TKUnit.assert(bindOptions.targetProperty === "targetBindProperty", "Expected: targetBindProperty, Actual: " + bindOptions.targetProperty);
|
||||
TKUnit.assert(bindOptions.expression === null, "Expected: null, Actual: " + bindOptions.expression);
|
||||
TKUnit.assert(bindOptions.twoWay === true, "Expected: true, Actual: " + bindOptions.twoWay);
|
||||
}
|
||||
|
||||
export var test_getBindableOptionsFromStringTwoParamsFormat = function () {
|
||||
var bindingExpression = "bindProperty, bindProperty * 2";
|
||||
var bindOptions = bindable.Bindable._getBindingOptions("targetBindProperty", bindingExpression);
|
||||
|
||||
TKUnit.assert(bindOptions.sourceProperty === "bindProperty", "Expected: bindProperty, Actual: " + bindOptions.sourceProperty);
|
||||
TKUnit.assert(bindOptions.targetProperty === "targetBindProperty", "Expected: targetBindProperty, Actual: " + bindOptions.targetProperty);
|
||||
TKUnit.assert(bindOptions.expression === "bindProperty * 2", "Expected: bindProperty * 2, Actual:" + bindOptions.expression);
|
||||
TKUnit.assert(bindOptions.twoWay === true, "Expected: true, Actual: " + bindOptions.twoWay);
|
||||
}
|
@ -88,13 +88,7 @@ export class ObservableArray<T> extends observable.Observable implements observa
|
||||
*/
|
||||
concat(): T[] {
|
||||
this._addArgs.index = this._array.length;
|
||||
|
||||
var result = this._array.concat.apply(this._array, arguments);
|
||||
|
||||
this._addArgs.addedCount = result.length - this._array.length;
|
||||
|
||||
this.notify(this._addArgs);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -117,6 +111,7 @@ export class ObservableArray<T> extends observable.Observable implements observa
|
||||
this._deleteArgs.removed = [result];
|
||||
|
||||
this.notify(this._deleteArgs);
|
||||
this._notifyLengthChange();
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -143,10 +138,16 @@ export class ObservableArray<T> extends observable.Observable implements observa
|
||||
this._addArgs.addedCount = this._array.length - this._addArgs.index;
|
||||
|
||||
this.notify(this._addArgs);
|
||||
this._notifyLengthChange();
|
||||
|
||||
return this._array.length;
|
||||
}
|
||||
|
||||
_notifyLengthChange() {
|
||||
var lengthChangedData = this._createPropertyChangeData("length", this._array.length);
|
||||
this.notify(lengthChangedData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the elements in an Array.
|
||||
*/
|
||||
@ -164,6 +165,7 @@ export class ObservableArray<T> extends observable.Observable implements observa
|
||||
this._deleteArgs.removed = [result];
|
||||
|
||||
this.notify(this._deleteArgs);
|
||||
this._notifyLengthChange();
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -202,6 +204,9 @@ export class ObservableArray<T> extends observable.Observable implements observa
|
||||
removed: result,
|
||||
addedCount: this._array.length > length ? this._array.length - length : 0
|
||||
});
|
||||
if (this._array.length !== length) {
|
||||
this._notifyLengthChange();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -218,6 +223,7 @@ export class ObservableArray<T> extends observable.Observable implements observa
|
||||
this._addArgs.addedCount = result - length;
|
||||
|
||||
this.notify(this._addArgs);
|
||||
this._notifyLengthChange();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ export function getComponentModule(elementName: string, namespace: string, attri
|
||||
gridLayoutModule.GridLayout.setColumnSpan(instance, !isNaN(+attrValue) && +attrValue);
|
||||
} else if (attr === ROW_SPAN) {
|
||||
gridLayoutModule.GridLayout.setRowSpan(instance, !isNaN(+attrValue) && +attrValue);
|
||||
} if (attr === LEFT) {
|
||||
} else if (attr === LEFT) {
|
||||
absoluteLayoutDef.AbsoluteLayout.setLeft(instance, !isNaN(+attrValue) && +attrValue);
|
||||
} else if (attr === TOP) {
|
||||
absoluteLayoutDef.AbsoluteLayout.setTop(instance, !isNaN(+attrValue) && +attrValue);
|
||||
|
@ -120,7 +120,7 @@ export class Bindable extends dependencyObservable.DependencyObservable implemen
|
||||
private static extractPropertyNameFromExpression(expression: string): string {
|
||||
var firstExpressionSymbolIndex = expression.search(expressionSymbolsRegex);
|
||||
if (firstExpressionSymbolIndex > -1) {
|
||||
return expression.substr(0, firstExpressionSymbolIndex);
|
||||
return expression.substr(0, firstExpressionSymbolIndex).trim();
|
||||
}
|
||||
else {
|
||||
return expression;
|
||||
@ -135,9 +135,16 @@ export class Bindable extends dependencyObservable.DependencyObservable implemen
|
||||
};
|
||||
if (types.isString(bindingExpression)) {
|
||||
var params = bindingExpression.split(",");
|
||||
result.sourceProperty = Bindable.extractPropertyNameFromExpression(params[0]);
|
||||
result.expression = params[1];
|
||||
result.twoWay = params[2] ? params[2].toLowerCase() === "true" : true;
|
||||
if (params.length === 1) {
|
||||
result.sourceProperty = Bindable.extractPropertyNameFromExpression(params[0].trim());
|
||||
result.expression = params[0].search(expressionSymbolsRegex) > -1 ? params[0].trim() : null;
|
||||
result.twoWay = true;
|
||||
}
|
||||
else {
|
||||
result.sourceProperty = Bindable.extractPropertyNameFromExpression(params[0].trim());
|
||||
result.expression = params[1].trim();
|
||||
result.twoWay = params[2] ? params[2].toLowerCase().trim() === "true" : true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -276,7 +283,6 @@ export class Binding {
|
||||
this.sourceOptions.property in sourceOptionsInstance) {
|
||||
value = sourceOptionsInstance[this.sourceOptions.property];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user