mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
@@ -1,5 +1,5 @@
|
|||||||
// >> observable-require
|
// >> observable-require
|
||||||
import * as observable from "data/observable";
|
import { Observable, fromObject, fromObjectRecursive, PropertyChangeData, EventData, WrappedValue } from "data/observable";
|
||||||
// << observable-require
|
// << observable-require
|
||||||
|
|
||||||
import * as dependencyObservable from "ui/core/dependency-observable";
|
import * as dependencyObservable from "ui/core/dependency-observable";
|
||||||
@@ -9,7 +9,7 @@ import * as proxy from "ui/core/proxy";
|
|||||||
import { ObservableArray } from "data/observable-array";
|
import { ObservableArray } from "data/observable-array";
|
||||||
|
|
||||||
var TESTED_NAME = "tested";
|
var TESTED_NAME = "tested";
|
||||||
class TestObservable extends observable.Observable {
|
class TestObservable extends Observable {
|
||||||
public test() {
|
public test() {
|
||||||
this._emit(TESTED_NAME);
|
this._emit(TESTED_NAME);
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ export var test_Observable_Constructor = function () {
|
|||||||
Age: 34,
|
Age: 34,
|
||||||
Married: true
|
Married: true
|
||||||
};
|
};
|
||||||
var person = new observable.Observable(json);
|
var person = fromObject(json);
|
||||||
var name = person.get("Name");
|
var name = person.get("Name");
|
||||||
var age = person.get("Age");
|
var age = person.get("Age");
|
||||||
var married = person.get("Married");
|
var married = person.get("Married");
|
||||||
@@ -35,11 +35,11 @@ export var test_Observable_Constructor = function () {
|
|||||||
|
|
||||||
export var tests_DummyTestForCodeSnippet = function () {
|
export var tests_DummyTestForCodeSnippet = function () {
|
||||||
// >> observable-property-change
|
// >> observable-property-change
|
||||||
var person = new observable.Observable();
|
var person = new Observable();
|
||||||
person.set("Name", "John");
|
person.set("Name", "John");
|
||||||
person.set("Age", 34);
|
person.set("Age", 34);
|
||||||
person.set("Married", true);
|
person.set("Married", true);
|
||||||
person.addEventListener(observable.Observable.propertyChangeEvent, function (pcd: observable.PropertyChangeData) {
|
person.addEventListener(Observable.propertyChangeEvent, function (pcd: PropertyChangeData) {
|
||||||
//console.log(pcd.eventName.toString() + " " + pcd.propertyName.toString() + " " + pcd.value.toString());
|
//console.log(pcd.eventName.toString() + " " + pcd.propertyName.toString() + " " + pcd.value.toString());
|
||||||
});
|
});
|
||||||
person.set("Age", 35);
|
person.set("Age", 35);
|
||||||
@@ -51,7 +51,7 @@ export var tests_DummyTestForCodeSnippet = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export var test_Observable_Members = function () {
|
export var test_Observable_Members = function () {
|
||||||
var obj = new observable.Observable();
|
var obj = new Observable();
|
||||||
TKUnit.assert(types.isDefined(obj.addEventListener), "Observable.addEventListener not defined");
|
TKUnit.assert(types.isDefined(obj.addEventListener), "Observable.addEventListener not defined");
|
||||||
TKUnit.assert(types.isDefined(obj._createPropertyChangeData), "Observable.createPropertyChangeData not defined");
|
TKUnit.assert(types.isDefined(obj._createPropertyChangeData), "Observable.createPropertyChangeData not defined");
|
||||||
TKUnit.assert(types.isDefined(obj._emit), "Observable.emit not defined");
|
TKUnit.assert(types.isDefined(obj._emit), "Observable.emit not defined");
|
||||||
@@ -62,19 +62,18 @@ export var test_Observable_Members = function () {
|
|||||||
TKUnit.assert(types.isDefined(obj.on), "Observable.on not defined");
|
TKUnit.assert(types.isDefined(obj.on), "Observable.on not defined");
|
||||||
TKUnit.assert(types.isDefined(obj.removeEventListener), "Observable.removeEventListener not defined");
|
TKUnit.assert(types.isDefined(obj.removeEventListener), "Observable.removeEventListener not defined");
|
||||||
TKUnit.assert(types.isDefined(obj.set), "Observable.set not defined");
|
TKUnit.assert(types.isDefined(obj.set), "Observable.set not defined");
|
||||||
TKUnit.assert(types.isDefined(obj.typeName), "Observable.typeName not defined");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export var test_Observable_UpdateAnotherPropertyWithinChangedCallback = function () {
|
export var test_Observable_UpdateAnotherPropertyWithinChangedCallback = function () {
|
||||||
var obj = new observable.Observable();
|
var obj = new Observable();
|
||||||
|
|
||||||
var changedCallback = function (pcd: observable.PropertyChangeData) {
|
var changedCallback = function (pcd: PropertyChangeData) {
|
||||||
if (pcd.propertyName === "name") {
|
if (pcd.propertyName === "name") {
|
||||||
pcd.object.set("test", "Changed test");
|
pcd.object.set("test", "Changed test");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, changedCallback);
|
obj.addEventListener(Observable.propertyChangeEvent, changedCallback);
|
||||||
|
|
||||||
obj.set("name", "Initial name");
|
obj.set("name", "Initial name");
|
||||||
obj.set("test", "Initial test");
|
obj.set("test", "Initial test");
|
||||||
@@ -129,18 +128,18 @@ export var test_DependencyObservable_UpdateAnotherPropertyWithinChangedCallback
|
|||||||
}
|
}
|
||||||
|
|
||||||
export var test_Observable_addEventListener_SingleEvent = function () {
|
export var test_Observable_addEventListener_SingleEvent = function () {
|
||||||
var obj = new observable.Observable();
|
var obj = new Observable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.PropertyChangeData) {
|
var callback = function (data: PropertyChangeData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
TKUnit.assert(data.eventName === observable.Observable.propertyChangeEvent, "Expected event name " + observable.Observable.propertyChangeEvent);
|
TKUnit.assert(data.eventName === Observable.propertyChangeEvent, "Expected event name " + Observable.propertyChangeEvent);
|
||||||
TKUnit.assert(data.object === obj, "PropertyChangeData.object value not valid.");
|
TKUnit.assert(data.object === obj, "PropertyChangeData.object value not valid.");
|
||||||
TKUnit.assert(data.propertyName === "testName", "PropertyChangeData.propertyName value not valid.");
|
TKUnit.assert(data.propertyName === "testName", "PropertyChangeData.propertyName value not valid.");
|
||||||
TKUnit.assert(data.value === 1, "PropertyChangeData.value value not valid.");
|
TKUnit.assert(data.value === 1, "PropertyChangeData.value value not valid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback);
|
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
TKUnit.assert(receivedCount === 1, "PropertyChanged event not raised properly.");
|
TKUnit.assert(receivedCount === 1, "PropertyChanged event not raised properly.");
|
||||||
}
|
}
|
||||||
@@ -149,13 +148,13 @@ export var test_Observable_addEventListener_MultipleEvents = function () {
|
|||||||
var obj = new TestObservable();
|
var obj = new TestObservable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.EventData) {
|
var callback = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
TKUnit.assert(data.object === obj, "EventData.object value not valid.");
|
TKUnit.assert(data.object === obj, "EventData.object value not valid.");
|
||||||
|
|
||||||
if (data.eventName === observable.Observable.propertyChangeEvent) {
|
if (data.eventName === Observable.propertyChangeEvent) {
|
||||||
var propertyData = <observable.PropertyChangeData>data;
|
var propertyData = <PropertyChangeData>data;
|
||||||
TKUnit.assert(propertyData.eventName === observable.Observable.propertyChangeEvent, "Expected event name " + observable.Observable.propertyChangeEvent);
|
TKUnit.assert(propertyData.eventName === Observable.propertyChangeEvent, "Expected event name " + Observable.propertyChangeEvent);
|
||||||
TKUnit.assert(propertyData.propertyName === "testName", "PropertyChangeData.propertyName value not valid.");
|
TKUnit.assert(propertyData.propertyName === "testName", "PropertyChangeData.propertyName value not valid.");
|
||||||
TKUnit.assert(propertyData.value === 1, "PropertyChangeData.value value not valid.");
|
TKUnit.assert(propertyData.value === 1, "PropertyChangeData.value value not valid.");
|
||||||
} else {
|
} else {
|
||||||
@@ -163,7 +162,7 @@ export var test_Observable_addEventListener_MultipleEvents = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = observable.Observable.propertyChangeEvent + "," + TESTED_NAME;
|
var events = Observable.propertyChangeEvent + "," + TESTED_NAME;
|
||||||
obj.addEventListener(events, callback);
|
obj.addEventListener(events, callback);
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
obj.test();
|
obj.test();
|
||||||
@@ -174,13 +173,13 @@ export var test_Observable_addEventListener_MultipleEvents_ShouldTrim = function
|
|||||||
var obj = new TestObservable();
|
var obj = new TestObservable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.EventData) {
|
var callback = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = observable.Observable.propertyChangeEvent + " , " + TESTED_NAME;
|
var events = Observable.propertyChangeEvent + " , " + TESTED_NAME;
|
||||||
obj.addEventListener(events, callback);
|
obj.addEventListener(events, callback);
|
||||||
TKUnit.assert(obj.hasListeners(observable.Observable.propertyChangeEvent), "Observable.addEventListener for multiple events should trim each event name.");
|
TKUnit.assert(obj.hasListeners(Observable.propertyChangeEvent), "Observable.addEventListener for multiple events should trim each event name.");
|
||||||
TKUnit.assert(obj.hasListeners(TESTED_NAME), "Observable.addEventListener for multiple events should trim each event name.");
|
TKUnit.assert(obj.hasListeners(TESTED_NAME), "Observable.addEventListener for multiple events should trim each event name.");
|
||||||
|
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
@@ -193,16 +192,16 @@ export var test_Observable_addEventListener_MultipleCallbacks = function () {
|
|||||||
var obj = new TestObservable();
|
var obj = new TestObservable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback1 = function (data: observable.EventData) {
|
var callback1 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback2 = function (data: observable.EventData) {
|
var callback2 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback1);
|
obj.addEventListener(Observable.propertyChangeEvent, callback1);
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback2);
|
obj.addEventListener(Observable.propertyChangeEvent, callback2);
|
||||||
|
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
TKUnit.assert(receivedCount === 2, "The propertyChanged notification should be raised twice.");
|
TKUnit.assert(receivedCount === 2, "The propertyChanged notification should be raised twice.");
|
||||||
@@ -212,15 +211,15 @@ export var test_Observable_addEventListener_MultipleCallbacks_MultipleEvents = f
|
|||||||
var obj = new TestObservable();
|
var obj = new TestObservable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback1 = function (data: observable.EventData) {
|
var callback1 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback2 = function (data: observable.EventData) {
|
var callback2 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = observable.Observable.propertyChangeEvent + " , " + TESTED_NAME;
|
var events = Observable.propertyChangeEvent + " , " + TESTED_NAME;
|
||||||
obj.addEventListener(events, callback1);
|
obj.addEventListener(events, callback1);
|
||||||
obj.addEventListener(events, callback2);
|
obj.addEventListener(events, callback2);
|
||||||
|
|
||||||
@@ -231,47 +230,47 @@ export var test_Observable_addEventListener_MultipleCallbacks_MultipleEvents = f
|
|||||||
}
|
}
|
||||||
|
|
||||||
export var test_Observable_removeEventListener_SingleEvent_SingleCallback = function () {
|
export var test_Observable_removeEventListener_SingleEvent_SingleCallback = function () {
|
||||||
var obj = new observable.Observable();
|
var obj = new Observable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.EventData) {
|
var callback = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback);
|
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
|
|
||||||
obj.removeEventListener(observable.Observable.propertyChangeEvent, callback);
|
obj.removeEventListener(Observable.propertyChangeEvent, callback);
|
||||||
TKUnit.assert(!obj.hasListeners(observable.Observable.propertyChangeEvent), "Observable.removeEventListener not working properly.");
|
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), "Observable.removeEventListener not working properly.");
|
||||||
|
|
||||||
obj.set("testName", 2);
|
obj.set("testName", 2);
|
||||||
TKUnit.assert(receivedCount === 1, "Observable.removeEventListener not working properly.");
|
TKUnit.assert(receivedCount === 1, "Observable.removeEventListener not working properly.");
|
||||||
}
|
}
|
||||||
|
|
||||||
export var test_Observable_removeEventListener_SingleEvent_MultipleCallbacks = function () {
|
export var test_Observable_removeEventListener_SingleEvent_MultipleCallbacks = function () {
|
||||||
var obj = new observable.Observable();
|
var obj = new Observable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback1 = function (data: observable.EventData) {
|
var callback1 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback2 = function (data: observable.EventData) {
|
var callback2 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback1);
|
obj.addEventListener(Observable.propertyChangeEvent, callback1);
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback2);
|
obj.addEventListener(Observable.propertyChangeEvent, callback2);
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
|
|
||||||
obj.removeEventListener(observable.Observable.propertyChangeEvent, callback1);
|
obj.removeEventListener(Observable.propertyChangeEvent, callback1);
|
||||||
TKUnit.assert(obj.hasListeners(observable.Observable.propertyChangeEvent), "Observable.removeEventListener not working properly with multiple listeners.");
|
TKUnit.assert(obj.hasListeners(Observable.propertyChangeEvent), "Observable.removeEventListener not working properly with multiple listeners.");
|
||||||
|
|
||||||
obj.set("testName", 2);
|
obj.set("testName", 2);
|
||||||
TKUnit.assert(receivedCount === 3, "Observable.removeEventListener not working properly with multiple listeners.");
|
TKUnit.assert(receivedCount === 3, "Observable.removeEventListener not working properly with multiple listeners.");
|
||||||
|
|
||||||
obj.removeEventListener(observable.Observable.propertyChangeEvent, callback2);
|
obj.removeEventListener(Observable.propertyChangeEvent, callback2);
|
||||||
TKUnit.assert(!obj.hasListeners(observable.Observable.propertyChangeEvent), "Observable.removeEventListener not working properly with multiple listeners.");
|
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), "Observable.removeEventListener not working properly with multiple listeners.");
|
||||||
|
|
||||||
obj.set("testName", 3);
|
obj.set("testName", 3);
|
||||||
TKUnit.assert(receivedCount === 3, "Observable.removeEventListener not working properly with multiple listeners.");
|
TKUnit.assert(receivedCount === 3, "Observable.removeEventListener not working properly with multiple listeners.");
|
||||||
@@ -281,11 +280,11 @@ export var test_Observable_removeEventListener_MutlipleEvents_SingleCallback = f
|
|||||||
var obj = new TestObservable();
|
var obj = new TestObservable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.EventData) {
|
var callback = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = observable.Observable.propertyChangeEvent + " , " + TESTED_NAME;
|
var events = Observable.propertyChangeEvent + " , " + TESTED_NAME;
|
||||||
obj.addEventListener(events, callback);
|
obj.addEventListener(events, callback);
|
||||||
|
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
@@ -293,7 +292,7 @@ export var test_Observable_removeEventListener_MutlipleEvents_SingleCallback = f
|
|||||||
|
|
||||||
obj.removeEventListener(events, callback);
|
obj.removeEventListener(events, callback);
|
||||||
|
|
||||||
TKUnit.assert(!obj.hasListeners(observable.Observable.propertyChangeEvent), "Expected result for hasObservers is false");
|
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), "Expected result for hasObservers is false");
|
||||||
TKUnit.assert(!obj.hasListeners(TESTED_NAME), "Expected result for hasObservers is false.");
|
TKUnit.assert(!obj.hasListeners(TESTED_NAME), "Expected result for hasObservers is false.");
|
||||||
|
|
||||||
obj.set("testName", 2);
|
obj.set("testName", 2);
|
||||||
@@ -306,21 +305,21 @@ export var test_Observable_removeEventListener_SingleEvent_NoCallbackSpecified =
|
|||||||
var obj = new TestObservable();
|
var obj = new TestObservable();
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback1 = function (data: observable.EventData) {
|
var callback1 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback2 = function (data: observable.EventData) {
|
var callback2 = function (data: EventData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback1);
|
obj.addEventListener(Observable.propertyChangeEvent, callback1);
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback2);
|
obj.addEventListener(Observable.propertyChangeEvent, callback2);
|
||||||
|
|
||||||
obj.set("testName", 1);
|
obj.set("testName", 1);
|
||||||
obj.removeEventListener(observable.Observable.propertyChangeEvent);
|
obj.removeEventListener(Observable.propertyChangeEvent);
|
||||||
|
|
||||||
TKUnit.assert(!obj.hasListeners(observable.Observable.propertyChangeEvent), "Expected result for hasObservers is false.");
|
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), "Expected result for hasObservers is false.");
|
||||||
|
|
||||||
obj.set("testName", 2);
|
obj.set("testName", 2);
|
||||||
TKUnit.assert(receivedCount === 2, "Expected receive count is 2");
|
TKUnit.assert(receivedCount === 2, "Expected receive count is 2");
|
||||||
@@ -330,18 +329,18 @@ export var test_Observable_WhenCreatedWithJSON_PropertyChangedWithDotNotation_Ra
|
|||||||
var json = {
|
var json = {
|
||||||
count: 5
|
count: 5
|
||||||
};
|
};
|
||||||
var obj = new observable.Observable(json);
|
var obj = fromObject(json);
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.PropertyChangeData) {
|
var callback = function (data: PropertyChangeData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
TKUnit.assert(data.eventName === observable.Observable.propertyChangeEvent, "Expected event name " + observable.Observable.propertyChangeEvent);
|
TKUnit.assert(data.eventName === Observable.propertyChangeEvent, "Expected event name " + Observable.propertyChangeEvent);
|
||||||
TKUnit.assert(data.object === obj, "PropertyChangeData.object value not valid.");
|
TKUnit.assert(data.object === obj, "PropertyChangeData.object value not valid.");
|
||||||
TKUnit.assert(data.propertyName === "count", "PropertyChangeData.propertyName value not valid.");
|
TKUnit.assert(data.propertyName === "count", "PropertyChangeData.propertyName value not valid.");
|
||||||
TKUnit.assert(data.value === 6, "PropertyChangeData.value value not valid.");
|
TKUnit.assert(data.value === 6, "PropertyChangeData.value value not valid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback);
|
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||||
|
|
||||||
(<any>obj).count++;
|
(<any>obj).count++;
|
||||||
|
|
||||||
@@ -352,18 +351,18 @@ export var test_Observable_WhenCreatedWithJSON_PropertyChangedWithBracketsNotati
|
|||||||
var json = {
|
var json = {
|
||||||
count: 5
|
count: 5
|
||||||
};
|
};
|
||||||
var obj = new observable.Observable(json);
|
var obj = fromObject(json);
|
||||||
|
|
||||||
var receivedCount = 0;
|
var receivedCount = 0;
|
||||||
var callback = function (data: observable.PropertyChangeData) {
|
var callback = function (data: PropertyChangeData) {
|
||||||
receivedCount++;
|
receivedCount++;
|
||||||
TKUnit.assert(data.eventName === observable.Observable.propertyChangeEvent, "Expected event name " + observable.Observable.propertyChangeEvent);
|
TKUnit.assert(data.eventName === Observable.propertyChangeEvent, "Expected event name " + Observable.propertyChangeEvent);
|
||||||
TKUnit.assert(data.object === obj, "PropertyChangeData.object value not valid.");
|
TKUnit.assert(data.object === obj, "PropertyChangeData.object value not valid.");
|
||||||
TKUnit.assert(data.propertyName === "count", "PropertyChangeData.propertyName value not valid.");
|
TKUnit.assert(data.propertyName === "count", "PropertyChangeData.propertyName value not valid.");
|
||||||
TKUnit.assert(data.value === 6, "PropertyChangeData.value value not valid.");
|
TKUnit.assert(data.value === 6, "PropertyChangeData.value value not valid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.addEventListener(observable.Observable.propertyChangeEvent, callback);
|
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||||
|
|
||||||
obj["count"]++;
|
obj["count"]++;
|
||||||
|
|
||||||
@@ -371,25 +370,25 @@ export var test_Observable_WhenCreatedWithJSON_PropertyChangedWithBracketsNotati
|
|||||||
}
|
}
|
||||||
|
|
||||||
export var test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAllEvents = function () {
|
export var test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAllEvents = function () {
|
||||||
var observableInstance = new observable.Observable();
|
var observableInstance = new Observable();
|
||||||
var firstHandlerCalled = false;
|
var firstHandlerCalled = false;
|
||||||
var secondHandlerCalled = false;
|
var secondHandlerCalled = false;
|
||||||
|
|
||||||
var firstHandler = function (args) {
|
var firstHandler = function (args) {
|
||||||
observableInstance.off(observable.Observable.propertyChangeEvent, firstHandler, firstObserver);
|
observableInstance.off(Observable.propertyChangeEvent, firstHandler, firstObserver);
|
||||||
firstHandlerCalled = true;
|
firstHandlerCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var secondHandler = function (args) {
|
var secondHandler = function (args) {
|
||||||
observableInstance.off(observable.Observable.propertyChangeEvent, secondHandler, secondObserver);
|
observableInstance.off(Observable.propertyChangeEvent, secondHandler, secondObserver);
|
||||||
secondHandlerCalled = true;
|
secondHandlerCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstObserver = new observable.Observable();
|
var firstObserver = new Observable();
|
||||||
var secondObserver = new observable.Observable();
|
var secondObserver = new Observable();
|
||||||
|
|
||||||
observableInstance.on(observable.Observable.propertyChangeEvent, firstHandler, firstObserver);
|
observableInstance.on(Observable.propertyChangeEvent, firstHandler, firstObserver);
|
||||||
observableInstance.on(observable.Observable.propertyChangeEvent, secondHandler, secondObserver);
|
observableInstance.on(Observable.propertyChangeEvent, secondHandler, secondObserver);
|
||||||
|
|
||||||
observableInstance.set("someProperty", "some value");
|
observableInstance.set("someProperty", "some value");
|
||||||
|
|
||||||
@@ -400,8 +399,8 @@ export var test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAllEven
|
|||||||
export var test_ObservableCreatedWithJSON_shouldDistinguishSeparateObjects = function () {
|
export var test_ObservableCreatedWithJSON_shouldDistinguishSeparateObjects = function () {
|
||||||
var obj1 = { val: 1 };
|
var obj1 = { val: 1 };
|
||||||
var obj2 = { val: 2 };
|
var obj2 = { val: 2 };
|
||||||
var observable1 = new observable.Observable(obj1);
|
var observable1 = fromObject(obj1);
|
||||||
var observable2 = new observable.Observable(obj2);
|
var observable2 = fromObject(obj2);
|
||||||
|
|
||||||
var val1 = observable1.get("val");
|
var val1 = observable1.get("val");
|
||||||
var val2 = observable2.get("val");
|
var val2 = observable2.get("val");
|
||||||
@@ -409,14 +408,14 @@ export var test_ObservableCreatedWithJSON_shouldDistinguishSeparateObjects = fun
|
|||||||
|
|
||||||
var propName1;
|
var propName1;
|
||||||
var newValue1;
|
var newValue1;
|
||||||
observable1.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => {
|
observable1.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||||
propName1 = data.propertyName;
|
propName1 = data.propertyName;
|
||||||
newValue1 = data.value;
|
newValue1 = data.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
var propName2;
|
var propName2;
|
||||||
var newValue2;
|
var newValue2;
|
||||||
observable2.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => {
|
observable2.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||||
propName2 = data.propertyName;
|
propName2 = data.propertyName;
|
||||||
newValue2 = data.value;
|
newValue2 = data.value;
|
||||||
});
|
});
|
||||||
@@ -435,8 +434,8 @@ export var test_ObservableCreatedWithJSON_shouldDistinguishSeparateObjects = fun
|
|||||||
};
|
};
|
||||||
|
|
||||||
export var test_ObservablesCreatedWithJSON_shouldNotInterfereWithOneAnother = function () {
|
export var test_ObservablesCreatedWithJSON_shouldNotInterfereWithOneAnother = function () {
|
||||||
var observable1 = new observable.Observable({ property1: 1 });
|
var observable1 = fromObject({ property1: 1 });
|
||||||
var observable2 = new observable.Observable({ property2: 2 });
|
var observable2 = fromObject({ property2: 2 });
|
||||||
|
|
||||||
TKUnit.assert(observable1.get("property1") === 1, `Expected: 1; Actual: ${observable1.get("property1")}`);
|
TKUnit.assert(observable1.get("property1") === 1, `Expected: 1; Actual: ${observable1.get("property1")}`);
|
||||||
TKUnit.assert(observable1.get("property2") === undefined, `Expected: undefined; Actual: ${observable1.get("property2")}`);
|
TKUnit.assert(observable1.get("property2") === undefined, `Expected: undefined; Actual: ${observable1.get("property2")}`);
|
||||||
@@ -446,14 +445,14 @@ export var test_ObservablesCreatedWithJSON_shouldNotInterfereWithOneAnother = fu
|
|||||||
|
|
||||||
var propName1;
|
var propName1;
|
||||||
var newValue1;
|
var newValue1;
|
||||||
observable1.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => {
|
observable1.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||||
propName1 = data.propertyName;
|
propName1 = data.propertyName;
|
||||||
newValue1 = data.value;
|
newValue1 = data.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
var propName2;
|
var propName2;
|
||||||
var newValue2;
|
var newValue2;
|
||||||
observable2.on(observable.Observable.propertyChangeEvent, (data: observable.PropertyChangeData) => {
|
observable2.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||||
propName2 = data.propertyName;
|
propName2 = data.propertyName;
|
||||||
newValue2 = data.value;
|
newValue2 = data.value;
|
||||||
});
|
});
|
||||||
@@ -468,12 +467,12 @@ export var test_ObservablesCreatedWithJSON_shouldNotInterfereWithOneAnother = fu
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function test_ObservablesCreatedWithJSON_shouldNotEmitTwoTimesPropertyChangeEvent() {
|
export function test_ObservablesCreatedWithJSON_shouldNotEmitTwoTimesPropertyChangeEvent() {
|
||||||
var testObservable = new observable.Observable({ "property1": 1 });
|
var testObservable = fromObject({ "property1": 1 });
|
||||||
var propertyChangeCounter = 0;
|
var propertyChangeCounter = 0;
|
||||||
var propertyChangeHandler = function (args) {
|
var propertyChangeHandler = function (args) {
|
||||||
propertyChangeCounter++;
|
propertyChangeCounter++;
|
||||||
}
|
}
|
||||||
testObservable.on(observable.Observable.propertyChangeEvent, propertyChangeHandler);
|
testObservable.on(Observable.propertyChangeEvent, propertyChangeHandler);
|
||||||
testObservable.set("property1", 2);
|
testObservable.set("property1", 2);
|
||||||
|
|
||||||
TKUnit.assertEqual(propertyChangeCounter, 1, "PropertyChange event should be fired only once for a single change.");
|
TKUnit.assertEqual(propertyChangeCounter, 1, "PropertyChange event should be fired only once for a single change.");
|
||||||
@@ -481,46 +480,46 @@ export function test_ObservablesCreatedWithJSON_shouldNotEmitTwoTimesPropertyCha
|
|||||||
|
|
||||||
export function test_ObservableShouldEmitPropertyChangeWithSameObjectUsingWrappedValue() {
|
export function test_ObservableShouldEmitPropertyChangeWithSameObjectUsingWrappedValue() {
|
||||||
var testArray = [1];
|
var testArray = [1];
|
||||||
var testObservable = new observable.Observable({ "property1": testArray});
|
var testObservable = fromObject({ "property1": testArray });
|
||||||
var propertyChangeCounter = 0;
|
var propertyChangeCounter = 0;
|
||||||
var propertyChangeHandler = function (args) {
|
var propertyChangeHandler = function (args) {
|
||||||
propertyChangeCounter++;
|
propertyChangeCounter++;
|
||||||
}
|
}
|
||||||
testObservable.on(observable.Observable.propertyChangeEvent, propertyChangeHandler);
|
testObservable.on(Observable.propertyChangeEvent, propertyChangeHandler);
|
||||||
testArray.push(2);
|
testArray.push(2);
|
||||||
|
|
||||||
testObservable.set("property1", testArray);
|
testObservable.set("property1", testArray);
|
||||||
|
|
||||||
TKUnit.assertEqual(propertyChangeCounter, 0, "PropertyChange event should not be fired when the same object instance is passed.");
|
TKUnit.assertEqual(propertyChangeCounter, 0, "PropertyChange event should not be fired when the same object instance is passed.");
|
||||||
|
|
||||||
testObservable.set("property1", observable.WrappedValue.wrap(testArray));
|
testObservable.set("property1", WrappedValue.wrap(testArray));
|
||||||
|
|
||||||
TKUnit.assertEqual(propertyChangeCounter, 1, "PropertyChange event should be fired only once for a single change.");
|
TKUnit.assertEqual(propertyChangeCounter, 1, "PropertyChange event should be fired only once for a single change.");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function test_CorrectEventArgsWhenWrappedValueIsUsed() {
|
export function test_CorrectEventArgsWhenWrappedValueIsUsed() {
|
||||||
let testArray = [1];
|
let testArray = [1];
|
||||||
let testObservable = new observable.Observable({ "property1": testArray});
|
let testObservable = fromObject({ "property1": testArray });
|
||||||
let actualArgsValue;
|
let actualArgsValue;
|
||||||
let propertyChangeHandler = function (args) {
|
let propertyChangeHandler = function (args) {
|
||||||
actualArgsValue = args.value;
|
actualArgsValue = args.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
testObservable.on(observable.Observable.propertyChangeEvent, propertyChangeHandler);
|
testObservable.on(Observable.propertyChangeEvent, propertyChangeHandler);
|
||||||
testArray.push(2);
|
testArray.push(2);
|
||||||
|
|
||||||
let wrappedArray = observable.WrappedValue.wrap(testArray);
|
let wrappedArray = WrappedValue.wrap(testArray);
|
||||||
|
|
||||||
testObservable.set("property1", wrappedArray);
|
testObservable.set("property1", wrappedArray);
|
||||||
|
|
||||||
TKUnit.assertEqual(actualArgsValue, wrappedArray, "PropertyChange event should be fired with correct value in arguments.");
|
TKUnit.assertEqual(actualArgsValue, testArray, "PropertyChange event should be fired with correct value in arguments.");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function test_CorrectPropertyValueAfterUsingWrappedValue() {
|
export function test_CorrectPropertyValueAfterUsingWrappedValue() {
|
||||||
let testArray = [1];
|
let testArray = [1];
|
||||||
let testObservable = new observable.Observable({ "property1": testArray});
|
let testObservable = fromObject({ "property1": testArray });
|
||||||
|
|
||||||
let wrappedArray = observable.WrappedValue.wrap(testArray);
|
let wrappedArray = WrappedValue.wrap(testArray);
|
||||||
|
|
||||||
testObservable.set("property1", wrappedArray);
|
testObservable.set("property1", wrappedArray);
|
||||||
|
|
||||||
@@ -529,7 +528,7 @@ export function test_CorrectPropertyValueAfterUsingWrappedValue() {
|
|||||||
|
|
||||||
export function test_NestedObservablesWithObservableArrayShouldNotCrash() {
|
export function test_NestedObservablesWithObservableArrayShouldNotCrash() {
|
||||||
let someObservableArray = new ObservableArray<any>();
|
let someObservableArray = new ObservableArray<any>();
|
||||||
let testObservable = observable.fromObjectRecursive({
|
let testObservable = fromObjectRecursive({
|
||||||
firstProp: "test string",
|
firstProp: "test string",
|
||||||
secondProp: someObservableArray
|
secondProp: someObservableArray
|
||||||
});
|
});
|
||||||
@@ -537,7 +536,7 @@ export function test_NestedObservablesWithObservableArrayShouldNotCrash() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function test_NestedObservableWithNullShouldNotCrash() {
|
export function test_NestedObservableWithNullShouldNotCrash() {
|
||||||
let testObservable = observable.fromObjectRecursive({
|
let testObservable = fromObjectRecursive({
|
||||||
someProperty: null
|
someProperty: null
|
||||||
});
|
});
|
||||||
TKUnit.assert(testObservable !== undefined);
|
TKUnit.assert(testObservable !== undefined);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ allTests["TIMER"] = require("./timer-tests");
|
|||||||
allTests["COLOR"] = require("./color-tests");
|
allTests["COLOR"] = require("./color-tests");
|
||||||
|
|
||||||
allTests["DEPENDENCY-OBSERVABLE"] = require("./ui/dependency-observable-tests");
|
allTests["DEPENDENCY-OBSERVABLE"] = require("./ui/dependency-observable-tests");
|
||||||
// allTests["BINDABLE"] = require("./ui/bindable-tests");
|
allTests["BINDABLE"] = require("./ui/bindable-tests");
|
||||||
allTests["BINDING-EXPRESSIONS"] = require("./ui/binding-expressions-tests");
|
allTests["BINDING-EXPRESSIONS"] = require("./ui/binding-expressions-tests");
|
||||||
allTests["XML-PARSER"] = require("./xml-parser-tests/xml-parser-tests");
|
allTests["XML-PARSER"] = require("./xml-parser-tests/xml-parser-tests");
|
||||||
allTests["FORMATTEDSTRING"] = require("./text/formatted-string-tests");
|
allTests["FORMATTEDSTRING"] = require("./text/formatted-string-tests");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Label } from "ui/label";
|
|||||||
import { Button } from "ui/button";
|
import { Button } from "ui/button";
|
||||||
import { Page } from "ui/page";
|
import { Page } from "ui/page";
|
||||||
import { View } from "ui/core/view";
|
import { View } from "ui/core/view";
|
||||||
import { Observable } from "data/observable";
|
import { fromObject } from "data/observable";
|
||||||
|
|
||||||
// >> actionbar-common-require
|
// >> actionbar-common-require
|
||||||
import * as actionBarModule from "ui/action-bar";
|
import * as actionBarModule from "ui/action-bar";
|
||||||
@@ -164,7 +164,7 @@ export function test_ActionBarItemBindingToEvent() {
|
|||||||
const firstHandler = function () { firstHandlerCallCounter++; };
|
const firstHandler = function () { firstHandlerCallCounter++; };
|
||||||
const secondHandler = function () { secondHandlerCallCounter++; };
|
const secondHandler = function () { secondHandlerCallCounter++; };
|
||||||
|
|
||||||
page.bindingContext = new Observable({ "test": firstHandler });
|
page.bindingContext = fromObject({ "test": firstHandler });
|
||||||
|
|
||||||
const actionBarItem = page.actionBar.actionItems.getItemAt(0);
|
const actionBarItem = page.actionBar.actionItems.getItemAt(0);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Observable, fromObjectRecursive } from "data/observable";
|
import { Observable, fromObject, fromObjectRecursive } from "data/observable";
|
||||||
import { ViewBase } from "ui/core/view-base";
|
import { ViewBase } from "ui/core/view-base";
|
||||||
import { BindingOptions } from "ui/core/bindable";
|
import { BindingOptions } from "ui/core/bindable";
|
||||||
import * as TKUnit from "../TKUnit";
|
import * as TKUnit from "../TKUnit";
|
||||||
@@ -25,7 +25,7 @@ import { TextField } from "ui/text-field";
|
|||||||
// </snippet>
|
// </snippet>
|
||||||
|
|
||||||
export function test_Bindable_Members() {
|
export function test_Bindable_Members() {
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
TKUnit.assert(types.isDefined(obj.bind), "Bindable.bind not defined");
|
TKUnit.assert(types.isDefined(obj.bind), "Bindable.bind not defined");
|
||||||
TKUnit.assert(types.isDefined(obj.unbind), "Bindable.unbind not defined");
|
TKUnit.assert(types.isDefined(obj.unbind), "Bindable.unbind not defined");
|
||||||
};
|
};
|
||||||
@@ -36,17 +36,17 @@ export function test_Bindable_Bind_ToTarget_OneWay() {
|
|||||||
|
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "name",
|
sourceProperty: "name",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options, model);
|
obj.bind(options, model);
|
||||||
|
|
||||||
TKUnit.assert(obj.get("test") === "John", "Expected result after binding is [test value] === 'John'");
|
TKUnit.assert(obj.get("text") === "John", "Expected result after binding is [test value] === 'John'");
|
||||||
|
|
||||||
model.set("name", "Changed");
|
model.set("name", "Changed");
|
||||||
|
|
||||||
TKUnit.assert(obj.get("test") === "Changed", "Expected result after binding is [test value] === 'Changed'");
|
TKUnit.assert(obj.get("text") === "Changed", "Expected result after binding is [test value] === 'Changed'");
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_Bindable_Bind_ToTarget_TwoWay() {
|
export function test_Bindable_Bind_ToTarget_TwoWay() {
|
||||||
@@ -55,19 +55,19 @@ export function test_Bindable_Bind_ToTarget_TwoWay() {
|
|||||||
|
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "name",
|
sourceProperty: "name",
|
||||||
targetProperty: "test",
|
targetProperty: "text",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options, model);
|
obj.bind(options, model);
|
||||||
obj.set("test", "Changed");
|
obj.set("text", "Changed");
|
||||||
|
|
||||||
TKUnit.assertEqual(model.get("name"), "Changed", "Two-way binding not updating the source when target is changed.");
|
TKUnit.assertEqual(model.get("name"), "Changed", "Two-way binding not updating the source when target is changed.");
|
||||||
|
|
||||||
model.set("name", "John");
|
model.set("name", "John");
|
||||||
|
|
||||||
TKUnit.assertEqual(obj.get("test"), "John", "Two-way binding not updating the target when source is changed.");
|
TKUnit.assertEqual(obj.get("text"), "John", "Two-way binding not updating the target when source is changed.");
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_Bindable_Bind_ToBindingContext_OneWay() {
|
export function test_Bindable_Bind_ToBindingContext_OneWay() {
|
||||||
@@ -76,15 +76,15 @@ export function test_Bindable_Bind_ToBindingContext_OneWay() {
|
|||||||
|
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "name",
|
sourceProperty: "name",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options);
|
obj.bind(options);
|
||||||
obj.set("test", "local");
|
obj.set("text", "local");
|
||||||
obj.bindingContext = model;
|
obj.bindingContext = model;
|
||||||
|
|
||||||
TKUnit.assert(obj.get("test") === "John", "Binding to a context does not update the target property.");
|
TKUnit.assert(obj.get("text") === "John", "Binding to a context does not update the target property.");
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_Bindable_Bind_ToBindingContext_TwoWay() {
|
export function test_Bindable_Bind_ToBindingContext_TwoWay() {
|
||||||
@@ -93,19 +93,19 @@ export function test_Bindable_Bind_ToBindingContext_TwoWay() {
|
|||||||
|
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "name",
|
sourceProperty: "name",
|
||||||
targetProperty: "test",
|
targetProperty: "text",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options);
|
obj.bind(options);
|
||||||
|
|
||||||
obj.set("test", "local");
|
obj.set("text", "local");
|
||||||
obj.bindingContext = model;
|
obj.bindingContext = model;
|
||||||
|
|
||||||
TKUnit.assertEqual(obj.get("test"), "John", "Binding to a context does not update the target property.");
|
TKUnit.assertEqual(obj.get("text"), "John", "Binding to a context does not update the target property.");
|
||||||
|
|
||||||
obj.set("test", "local");
|
obj.set("text", "local");
|
||||||
|
|
||||||
TKUnit.assertEqual(model.get("name"), "local", "Two-way binding to a context does not update the source property.");
|
TKUnit.assertEqual(model.get("name"), "local", "Two-way binding to a context does not update the source property.");
|
||||||
};
|
};
|
||||||
@@ -115,20 +115,20 @@ export function test_Bindable_Unbind() {
|
|||||||
|
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "name",
|
sourceProperty: "name",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options, model);
|
obj.bind(options, model);
|
||||||
|
|
||||||
model.set("name", "John");
|
model.set("name", "John");
|
||||||
|
|
||||||
TKUnit.assert(obj.get("test") === "John", "Binding does not updates target property.");
|
TKUnit.assert(obj.get("text") === "John", "Binding does not updates target property.");
|
||||||
|
|
||||||
obj.unbind("test");
|
obj.unbind("text");
|
||||||
model.set("name", "Changed");
|
model.set("name", "Changed");
|
||||||
|
|
||||||
TKUnit.assert(obj.get("test") === "John", "Unbind does not remove binding.");
|
TKUnit.assert(obj.get("text") === "John", "Unbind does not remove binding.");
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_bind_NoSource_WillUse_BindingContext() {
|
export function test_bind_NoSource_WillUse_BindingContext() {
|
||||||
@@ -233,7 +233,7 @@ export function test_OneBindableToBindMoreThanOneProperty_ToSameSource() {
|
|||||||
|
|
||||||
const firstPropertyOptions: BindingOptions = {
|
const firstPropertyOptions: BindingOptions = {
|
||||||
sourceProperty: "name",
|
sourceProperty: "name",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
};
|
};
|
||||||
|
|
||||||
const secondPropertyOptions: BindingOptions = {
|
const secondPropertyOptions: BindingOptions = {
|
||||||
@@ -241,14 +241,14 @@ export function test_OneBindableToBindMoreThanOneProperty_ToSameSource() {
|
|||||||
targetProperty: "targetProperty"
|
targetProperty: "targetProperty"
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(firstPropertyOptions, model);
|
obj.bind(firstPropertyOptions, model);
|
||||||
obj.bind(secondPropertyOptions, model);
|
obj.bind(secondPropertyOptions, model);
|
||||||
|
|
||||||
model.set("name", "John");
|
model.set("name", "John");
|
||||||
model.set("sourceProperty", "testValue");
|
model.set("sourceProperty", "testValue");
|
||||||
|
|
||||||
TKUnit.assertEqual(obj.get("test"), "John", "Binding does not updates target property.");
|
TKUnit.assertEqual(obj.get("text"), "John", "Binding does not updates target property.");
|
||||||
TKUnit.assertEqual(obj.get("targetProperty"), "testValue", "Binding does not updates target property1.");
|
TKUnit.assertEqual(obj.get("targetProperty"), "testValue", "Binding does not updates target property1.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,10 +260,10 @@ export function test_MoreThanOneBindables_BindToASameSourceAndProperty() {
|
|||||||
targetProperty: "targetProperty"
|
targetProperty: "targetProperty"
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj1 = new ViewBase();
|
const obj1 = new Label();
|
||||||
obj1.bind(bindingOptions, model);
|
obj1.bind(bindingOptions, model);
|
||||||
|
|
||||||
const obj2 = new ViewBase();
|
const obj2 = new Label();
|
||||||
obj2.bind(bindingOptions, model);
|
obj2.bind(bindingOptions, model);
|
||||||
|
|
||||||
model.set("sourceProperty", "testValue");
|
model.set("sourceProperty", "testValue");
|
||||||
@@ -285,7 +285,7 @@ class TestClass extends ViewBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_WhenBindingSetsInvalidValue_NoExptionIsThrown() {
|
export function test_WhenBindingSetsInvalidValue_NoExceptionIsThrown() {
|
||||||
const model = new Observable();
|
const model = new Observable();
|
||||||
|
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
@@ -357,27 +357,27 @@ export function test_binding_bindingContext_setBindingFirst() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function test_Bindable_BindingContext_Number_DoesNotThrow() {
|
export function test_Bindable_BindingContext_Number_DoesNotThrow() {
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bindingContext = 42;
|
obj.bindingContext = 42;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_Bindable_BindingContext_Boolean_DoesNotThrow() {
|
export function test_Bindable_BindingContext_Boolean_DoesNotThrow() {
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bindingContext = true;
|
obj.bindingContext = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_Bindable_BindingContext_String_DoesNotThrow() {
|
export function test_Bindable_BindingContext_String_DoesNotThrow() {
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "length",
|
sourceProperty: "length",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
};
|
};
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options);
|
obj.bind(options);
|
||||||
obj.set("test", "local");
|
obj.set("text", "local");
|
||||||
obj.bindingContext = "string";
|
obj.bindingContext = "string";
|
||||||
|
|
||||||
TKUnit.assert(obj.get("test") === 6, "Expected: 6; Actual: " + obj.get("test"));
|
TKUnit.assert(obj.get("text") === 6, "Expected: 6; Actual: " + obj.get("text"));
|
||||||
};
|
};
|
||||||
|
|
||||||
export function test_getBindableOptionsFromStringFullFormat() {
|
export function test_getBindableOptionsFromStringFullFormat() {
|
||||||
@@ -483,7 +483,7 @@ export function test_bindingToNestedPropertyWithValueSyntax() {
|
|||||||
const bindingSource = new Observable();
|
const bindingSource = new Observable();
|
||||||
bindingSource.set("testProperty", "testValue");
|
bindingSource.set("testProperty", "testValue");
|
||||||
|
|
||||||
const testElement = new ViewBase();
|
const testElement = new Label();
|
||||||
testElement.bind({
|
testElement.bind({
|
||||||
sourceProperty: "$value.testProperty",
|
sourceProperty: "$value.testProperty",
|
||||||
targetProperty: "targetPropertyName"
|
targetProperty: "targetPropertyName"
|
||||||
@@ -499,8 +499,8 @@ export function test_TwoElementsBindingToSameBindingContext() {
|
|||||||
const label1 = <Label>(page.getViewById("label1"));
|
const label1 = <Label>(page.getViewById("label1"));
|
||||||
const label2 = <Label>(page.getViewById("label2"));
|
const label2 = <Label>(page.getViewById("label2"));
|
||||||
|
|
||||||
TKUnit.assertEqual(upperStackLabel.text, label1.text);
|
TKUnit.assertEqual(upperStackLabel.text, label1.text, "label1");
|
||||||
TKUnit.assertEqual(upperStackLabel.text, label2.text);
|
TKUnit.assertEqual(upperStackLabel.text, label2.text, "label2");
|
||||||
};
|
};
|
||||||
const moduleName = __dirname.substr(fs.knownFolders.currentApp().path.length);
|
const moduleName = __dirname.substr(fs.knownFolders.currentApp().path.length);
|
||||||
helper.navigateToModuleAndRunTest(("." + moduleName + "/bindingContext_testPage"), null, testFunc);
|
helper.navigateToModuleAndRunTest(("." + moduleName + "/bindingContext_testPage"), null, testFunc);
|
||||||
@@ -662,28 +662,28 @@ export function test_UpdatingNestedPropertyViaBinding() {
|
|||||||
viewModel.set("parentView", parentViewModel);
|
viewModel.set("parentView", parentViewModel);
|
||||||
parentViewModel.set("name", expectedValue1);
|
parentViewModel.set("name", expectedValue1);
|
||||||
|
|
||||||
const testElement: ViewBase = new ViewBase();
|
const testElement = new Label();
|
||||||
|
|
||||||
testElement.bind({
|
testElement.bind({
|
||||||
sourceProperty: "parentView.name",
|
sourceProperty: "parentView.name",
|
||||||
targetProperty: "targetName",
|
targetProperty: "text",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, viewModel);
|
}, viewModel);
|
||||||
|
|
||||||
const testElement2: ViewBase = new ViewBase();
|
const testElement2 = new Label();
|
||||||
|
|
||||||
testElement2.bind({
|
testElement2.bind({
|
||||||
sourceProperty: "parentView.name",
|
sourceProperty: "parentView.name",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "text",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, viewModel);
|
}, viewModel);
|
||||||
|
|
||||||
TKUnit.assertEqual(testElement.get("targetName"), expectedValue1);
|
TKUnit.assertEqual(testElement.get("text"), expectedValue1);
|
||||||
|
|
||||||
testElement.set("targetName", expectedValue2);
|
testElement.set("text", expectedValue2);
|
||||||
|
|
||||||
TKUnit.assertEqual(parentViewModel.get("name"), expectedValue2);
|
TKUnit.assertEqual(parentViewModel.get("name"), expectedValue2);
|
||||||
TKUnit.assertEqual(testElement2.get("targetProperty"), expectedValue2);
|
TKUnit.assertEqual(testElement2.get("text"), expectedValue2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Person extends Observable {
|
class Person extends Observable {
|
||||||
@@ -754,7 +754,7 @@ export function test_NestedPropertiesBinding() {
|
|||||||
const viewModel = new Observable();
|
const viewModel = new Observable();
|
||||||
viewModel.set("activity", new Activity(expectedValue, "Default First Name", "Default Last Name"));
|
viewModel.set("activity", new Activity(expectedValue, "Default First Name", "Default Last Name"));
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "activity.Text",
|
sourceProperty: "activity.Text",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
@@ -783,7 +783,7 @@ export function test_WrongNestedPropertiesBinding() {
|
|||||||
};
|
};
|
||||||
trace.addWriter(traceWriter);
|
trace.addWriter(traceWriter);
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "activity.",
|
sourceProperty: "activity.",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
@@ -801,14 +801,14 @@ export function test_NestedPropertiesBindingTwoTargets() {
|
|||||||
const viewModel = new Observable();
|
const viewModel = new Observable();
|
||||||
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "activity.Text",
|
sourceProperty: "activity.Text",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, viewModel);
|
}, viewModel);
|
||||||
|
|
||||||
const target2 = new ViewBase();
|
const target2 = new Label();
|
||||||
target2.bind({
|
target2.bind({
|
||||||
sourceProperty: "activity.Owner.FirstName",
|
sourceProperty: "activity.Owner.FirstName",
|
||||||
targetProperty: "targetProp",
|
targetProperty: "targetProp",
|
||||||
@@ -836,14 +836,14 @@ export function test_NestedPropertiesBindingTwoTargetsAndSecondChange() {
|
|||||||
const viewModel = new Observable();
|
const viewModel = new Observable();
|
||||||
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "activity.Text",
|
sourceProperty: "activity.Text",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, viewModel);
|
}, viewModel);
|
||||||
|
|
||||||
const target2 = new ViewBase();
|
const target2 = new Label();
|
||||||
target2.bind({
|
target2.bind({
|
||||||
sourceProperty: "activity.Owner.FirstName",
|
sourceProperty: "activity.Owner.FirstName",
|
||||||
targetProperty: "targetProp",
|
targetProperty: "targetProp",
|
||||||
@@ -881,14 +881,14 @@ export function test_NestedPropertiesBindingTwoTargetsAndRegularChange() {
|
|||||||
const viewModel = new Observable();
|
const viewModel = new Observable();
|
||||||
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "activity.Text",
|
sourceProperty: "activity.Text",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, viewModel);
|
}, viewModel);
|
||||||
|
|
||||||
const target2 = new ViewBase();
|
const target2 = new Label();
|
||||||
target2.bind({
|
target2.bind({
|
||||||
sourceProperty: "activity.Owner.FirstName",
|
sourceProperty: "activity.Owner.FirstName",
|
||||||
targetProperty: "targetProp",
|
targetProperty: "targetProp",
|
||||||
@@ -925,14 +925,14 @@ export function test_NestedPropertiesBindingTwoTargetsAndReplacingSomeNestedObje
|
|||||||
const viewModel = new Observable();
|
const viewModel = new Observable();
|
||||||
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
viewModel.set("activity", new Activity(expectedText, expectedFirstName, expectedLastName));
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "activity.Text",
|
sourceProperty: "activity.Text",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, viewModel);
|
}, viewModel);
|
||||||
|
|
||||||
const target2 = new ViewBase();
|
const target2 = new Label();
|
||||||
target2.bind({
|
target2.bind({
|
||||||
sourceProperty: "activity.Owner.FirstName",
|
sourceProperty: "activity.Owner.FirstName",
|
||||||
targetProperty: "targetProp",
|
targetProperty: "targetProp",
|
||||||
@@ -965,7 +965,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndReplacingSomeNestedObje
|
|||||||
|
|
||||||
export function test_NullSourcePropertyShouldNotCrash() {
|
export function test_NullSourcePropertyShouldNotCrash() {
|
||||||
const expectedValue = "Expected Value";
|
const expectedValue = "Expected Value";
|
||||||
const target = new ViewBase();
|
const target = new Label();
|
||||||
const convFunc = function (value) {
|
const convFunc = function (value) {
|
||||||
return value + "Converted";
|
return value + "Converted";
|
||||||
};
|
};
|
||||||
@@ -1024,7 +1024,7 @@ export function test_BindingHitsGetterTooManyTimes() {
|
|||||||
const model = new Dummy();
|
const model = new Dummy();
|
||||||
model.dummyProperty = "OPA";
|
model.dummyProperty = "OPA";
|
||||||
|
|
||||||
const bindableObj = new ViewBase();
|
const bindableObj = new Label();
|
||||||
|
|
||||||
bindableObj.bind({ sourceProperty: "dummyProperty", targetProperty: "dummyTarget" }, model);
|
bindableObj.bind({ sourceProperty: "dummyProperty", targetProperty: "dummyTarget" }, model);
|
||||||
|
|
||||||
@@ -1032,53 +1032,53 @@ export function test_BindingHitsGetterTooManyTimes() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function test_SupportFunctionsInExpressions() {
|
export function test_SupportFunctionsInExpressions() {
|
||||||
const model = new Observable({
|
const model = fromObject({
|
||||||
"anyColor": "red",
|
"anyColor": "red",
|
||||||
"isVisible": function () {
|
"isVisible": function () {
|
||||||
return this.get("anyColor") === "red";
|
return this.get("anyColor") === "red";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const bindableObj = new ViewBase();
|
const bindableObj = new Label();
|
||||||
|
|
||||||
bindableObj.bind({
|
bindableObj.bind({
|
||||||
"sourceProperty": "$value",
|
"sourceProperty": "$value",
|
||||||
"targetProperty": "test",
|
"targetProperty": "text",
|
||||||
"expression": "isVisible() ? 'visible' : 'collapsed'"
|
"expression": "isVisible() ? 'visible' : 'collapsed'"
|
||||||
}, model);
|
}, model);
|
||||||
|
|
||||||
model.set("anyColor", "blue");
|
model.set("anyColor", "blue");
|
||||||
|
|
||||||
TKUnit.assertEqual(bindableObj.get("test"), "collapsed", "When anyColor is blue test property should be collapsed.");
|
TKUnit.assertEqual(bindableObj.get("text"), "collapsed", "When anyColor is blue test property should be collapsed.");
|
||||||
|
|
||||||
model.set("anyColor", "red");
|
model.set("anyColor", "red");
|
||||||
|
|
||||||
TKUnit.assertEqual(bindableObj.get("test"), "visible", "When anyColor is red test property should be visible.");
|
TKUnit.assertEqual(bindableObj.get("text"), "visible", "When anyColor is red test property should be visible.");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function test_$ValueSupportWithinExpression() {
|
export function test_$ValueSupportWithinExpression() {
|
||||||
const model = new Observable({
|
const model = fromObject({
|
||||||
"anyColor": "red",
|
"anyColor": "red",
|
||||||
"isVisible": function () {
|
"isVisible": function () {
|
||||||
return this.get("anyColor") === "red";
|
return this.get("anyColor") === "red";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const bindableObj = new ViewBase();
|
const bindableObj = new Label();
|
||||||
|
|
||||||
bindableObj.bind({
|
bindableObj.bind({
|
||||||
"sourceProperty": "$value",
|
"sourceProperty": "$value",
|
||||||
"targetProperty": "test",
|
"targetProperty": "text",
|
||||||
"expression": "$value.anyColor === 'red' ? 'red' : 'blue'"
|
"expression": "$value.anyColor === 'red' ? 'red' : 'blue'"
|
||||||
}, model);
|
}, model);
|
||||||
|
|
||||||
model.set("anyColor", "blue");
|
model.set("anyColor", "blue");
|
||||||
|
|
||||||
TKUnit.assertEqual(bindableObj.get("test"), "blue", "When anyColor is blue test property should be blue too.");
|
TKUnit.assertEqual(bindableObj.get("text"), "blue", "When anyColor is blue test property should be blue too.");
|
||||||
|
|
||||||
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("text"), "red", "When anyColor is red test property should be red too.");
|
||||||
TKUnit.assertTrue(model['$value'] === undefined, "We should not add $value to binding context.");
|
TKUnit.assertTrue(model['$value'] === undefined, "We should not add $value to binding context.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1141,14 +1141,14 @@ export function test_BindingToPropertiesWithSameNames() {
|
|||||||
secondsobject.secondsobject = 1;
|
secondsobject.secondsobject = 1;
|
||||||
model.item.secondsobject = secondsobject;
|
model.item.secondsobject = secondsobject;
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "item.seconds",
|
sourceProperty: "item.seconds",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, model);
|
}, model);
|
||||||
|
|
||||||
const target2 = new ViewBase();
|
const target2 = new Label();
|
||||||
target2.bind({
|
target2.bind({
|
||||||
sourceProperty: "item.secondsobject.secondsobject",
|
sourceProperty: "item.secondsobject.secondsobject",
|
||||||
targetProperty: "targetProp",
|
targetProperty: "targetProp",
|
||||||
@@ -1178,14 +1178,14 @@ export function test_BindingToPropertiesWithSameNamesSecondCase() {
|
|||||||
secondsobject.secondsobject = 1;
|
secondsobject.secondsobject = 1;
|
||||||
model.item.secondsobject = secondsobject;
|
model.item.secondsobject = secondsobject;
|
||||||
|
|
||||||
const target1 = new ViewBase();
|
const target1 = new Label();
|
||||||
target1.bind({
|
target1.bind({
|
||||||
sourceProperty: "item.seconds",
|
sourceProperty: "item.seconds",
|
||||||
targetProperty: "targetProperty",
|
targetProperty: "targetProperty",
|
||||||
twoWay: true
|
twoWay: true
|
||||||
}, model);
|
}, model);
|
||||||
|
|
||||||
const target2 = new ViewBase();
|
const target2 = new Label();
|
||||||
target2.bind({
|
target2.bind({
|
||||||
sourceProperty: "item.secondsobject.secondsobject",
|
sourceProperty: "item.secondsobject.secondsobject",
|
||||||
targetProperty: "targetProp",
|
targetProperty: "targetProp",
|
||||||
@@ -1239,10 +1239,10 @@ export function test_BindingToRelatedProps() {
|
|||||||
model.prop1 = false;
|
model.prop1 = false;
|
||||||
model.prop2 = "Alabala";
|
model.prop2 = "Alabala";
|
||||||
|
|
||||||
let target1 = new ViewBase();
|
let target1 = new Label();
|
||||||
target1.bind({ sourceProperty: 'prop1', targetProperty: 'targetProp1' }, model);
|
target1.bind({ sourceProperty: 'prop1', targetProperty: 'targetProp1' }, model);
|
||||||
|
|
||||||
let target2 = new ViewBase();
|
let target2 = new Label();
|
||||||
target2.bind({ sourceProperty: 'prop2', targetProperty: 'targetProp2' }, model);
|
target2.bind({ sourceProperty: 'prop2', targetProperty: 'targetProp2' }, model);
|
||||||
|
|
||||||
model.prop2 = "Tralala";
|
model.prop2 = "Tralala";
|
||||||
@@ -1253,11 +1253,11 @@ export function test_BindingToRelatedProps() {
|
|||||||
export function test_only_Bindable_BindingContext_Null_DoesNotThrow() {
|
export function test_only_Bindable_BindingContext_Null_DoesNotThrow() {
|
||||||
const options: BindingOptions = {
|
const options: BindingOptions = {
|
||||||
sourceProperty: "a.b",
|
sourceProperty: "a.b",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
};
|
};
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind(options);
|
obj.bind(options);
|
||||||
obj.bindingContext = new Observable({ a: "b" });
|
obj.bindingContext = fromObject({ a: "b" });
|
||||||
obj.bindingContext = null;
|
obj.bindingContext = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1271,15 +1271,15 @@ export function test_Observable_from_nested_json_binds_correctly() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind({
|
obj.bind({
|
||||||
sourceProperty: "firstObject.secondObject.dummyProperty",
|
sourceProperty: "firstObject.secondObject.dummyProperty",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
}, model);
|
}, model);
|
||||||
|
|
||||||
model.get("firstObject").get("secondObject").set("dummyProperty", expectedValue);
|
model.get("firstObject").get("secondObject").set("dummyProperty", expectedValue);
|
||||||
|
|
||||||
TKUnit.assertEqual(obj.get("test"), expectedValue);
|
TKUnit.assertEqual(obj.get("text"), expectedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function test_Observable_from_nested_json_binds_correctly_when_upper_object_is_changed() {
|
export function test_Observable_from_nested_json_binds_correctly_when_upper_object_is_changed() {
|
||||||
@@ -1292,15 +1292,15 @@ export function test_Observable_from_nested_json_binds_correctly_when_upper_obje
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const obj = new ViewBase();
|
const obj = new Label();
|
||||||
obj.bind({
|
obj.bind({
|
||||||
sourceProperty: "firstObject.secondObject.dummyProperty",
|
sourceProperty: "firstObject.secondObject.dummyProperty",
|
||||||
targetProperty: "test"
|
targetProperty: "text"
|
||||||
}, model);
|
}, model);
|
||||||
|
|
||||||
model.get("firstObject").set("secondObject", new Observable({ "dummyProperty": expectedValue }));
|
model.get("firstObject").set("secondObject", fromObject({ "dummyProperty": expectedValue }));
|
||||||
|
|
||||||
TKUnit.assertEqual(obj.get("test"), expectedValue);
|
TKUnit.assertEqual(obj.get("text"), expectedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function test_BindingToBindingContextProperty_ShouldUseNewContext() {
|
export function test_BindingToBindingContextProperty_ShouldUseNewContext() {
|
||||||
|
|||||||
11
tns-core-modules/data/observable/observable.d.ts
vendored
11
tns-core-modules/data/observable/observable.d.ts
vendored
@@ -70,16 +70,6 @@ declare module "data/observable" {
|
|||||||
*/
|
*/
|
||||||
public static propertyChangeEvent: string;
|
public static propertyChangeEvent: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* [Deprecated please use static functions fromJSON or fromJSONRecursive instead] Creates an Observable instance and sets its properties according to the supplied JSON object.
|
|
||||||
*/
|
|
||||||
constructor(json?: any);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name of the constructor function for this instance. E.g. for a Button class this will return "Button".
|
|
||||||
*/
|
|
||||||
typeName: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic method signature to hook an event listener (shortcut alias to the addEventListener method).
|
* A basic method signature to hook an event listener (shortcut alias to the addEventListener method).
|
||||||
* @param eventNames - String corresponding to events (e.g. "propertyChange"). Optionally could be used more events separated by `,` (e.g. "propertyChange", "change").
|
* @param eventNames - String corresponding to events (e.g. "propertyChange"). Optionally could be used more events separated by `,` (e.g. "propertyChange", "change").
|
||||||
@@ -145,7 +135,6 @@ declare module "data/observable" {
|
|||||||
/**
|
/**
|
||||||
* This method is intended to be overriden by inheritors to provide additional implementation.
|
* This method is intended to be overriden by inheritors to provide additional implementation.
|
||||||
*/
|
*/
|
||||||
_setCore(data: PropertyChangeData);
|
|
||||||
_createPropertyChangeData(name: string, value: any): PropertyChangeData;
|
_createPropertyChangeData(name: string, value: any): PropertyChangeData;
|
||||||
_emit(eventNames: string);
|
_emit(eventNames: string);
|
||||||
//@endprivate
|
//@endprivate
|
||||||
|
|||||||
@@ -1,43 +1,28 @@
|
|||||||
import * as types from "utils/types";
|
import { Observable as ObservableDefinition, WrappedValue as WrappedValueDefinition, EventData, PropertyChangeData } from "data/observable";
|
||||||
import * as definition from "data/observable";
|
|
||||||
|
|
||||||
interface ListenerEntry {
|
interface ListenerEntry {
|
||||||
callback: (data: definition.EventData) => void;
|
callback: (data: EventData) => void;
|
||||||
thisArg: any;
|
thisArg: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _wrappedIndex = 0;
|
let _wrappedIndex = 0;
|
||||||
|
|
||||||
export class WrappedValue implements definition.WrappedValue {
|
export class WrappedValue implements WrappedValueDefinition {
|
||||||
private _wrapped: any;
|
constructor(public wrapped: any) {
|
||||||
|
|
||||||
public get wrapped(): any {
|
|
||||||
return this._wrapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set wrapped(value) {
|
|
||||||
this._wrapped = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(value: any) {
|
|
||||||
this._wrapped = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unwrap(value: any) {
|
public static unwrap(value: any) {
|
||||||
if (value && value.wrapped) {
|
return (value && value.wrapped) ? value.wrapped : value;
|
||||||
return value.wrapped;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static wrap(value: any) {
|
public static wrap(value: any) {
|
||||||
var w = _wrappedValues[_wrappedIndex++ % 5];
|
const w = _wrappedValues[_wrappedIndex++ % 5];
|
||||||
w.wrapped = value;
|
w.wrapped = value;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _wrappedValues = [
|
let _wrappedValues = [
|
||||||
new WrappedValue(null),
|
new WrappedValue(null),
|
||||||
new WrappedValue(null),
|
new WrappedValue(null),
|
||||||
new WrappedValue(null),
|
new WrappedValue(null),
|
||||||
@@ -45,37 +30,26 @@ var _wrappedValues = [
|
|||||||
new WrappedValue(null)
|
new WrappedValue(null)
|
||||||
]
|
]
|
||||||
|
|
||||||
export class Observable implements definition.Observable {
|
export class Observable implements ObservableDefinition {
|
||||||
public static propertyChangeEvent = "propertyChange";
|
public static propertyChangeEvent = "propertyChange";
|
||||||
_map: Map<string, Object>;
|
|
||||||
|
|
||||||
private _observers = {};
|
private _observers = {};
|
||||||
|
|
||||||
constructor(source?: any) {
|
public get(name: string): any {
|
||||||
if (source) {
|
return this[name];
|
||||||
addPropertiesFromObject(this, source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_defineNewProperty(propertyName: string): void {
|
public set(name: string, value: any) {
|
||||||
Object.defineProperty(this, propertyName, {
|
// TODO: Parameter validation
|
||||||
get: function () {
|
if (this[name] === value) {
|
||||||
return this._map.get(propertyName);
|
return;
|
||||||
},
|
|
||||||
set: function (value) {
|
|
||||||
this._map.set(propertyName, value);
|
|
||||||
this.notify(this._createPropertyChangeData(propertyName, value));
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get typeName(): string {
|
const newValue = WrappedValue.unwrap(value);
|
||||||
return types.getClass(this);
|
this[name] = newValue;
|
||||||
|
this.notifyPropertyChange(name, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public on(eventNames: string, callback: (data: definition.EventData) => void, thisArg?: any) {
|
public on(eventNames: string, callback: (data: EventData) => void, thisArg?: any) {
|
||||||
this.addEventListener(eventNames, callback, thisArg);
|
this.addEventListener(eventNames, callback, thisArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,18 +57,19 @@ export class Observable implements definition.Observable {
|
|||||||
this.removeEventListener(eventNames, callback, thisArg);
|
this.removeEventListener(eventNames, callback, thisArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addEventListener(eventNames: string, callback: (data: definition.EventData) => void, thisArg?: any) {
|
public addEventListener(eventNames: string, callback: (data: EventData) => void, thisArg?: Object) {
|
||||||
if (!types.isString(eventNames)) {
|
if (typeof eventNames !== "string") {
|
||||||
throw new TypeError("Events name(s) must be string.");
|
throw new TypeError("Events name(s) must be string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
types.verifyCallback(callback);
|
if (typeof callback !== "function") {
|
||||||
|
throw new TypeError("callback must be function.");
|
||||||
|
}
|
||||||
|
|
||||||
var events: Array<string> = eventNames.split(",");
|
const events = eventNames.split(",");
|
||||||
|
for (let i = 0, l = events.length; i < l; i++) {
|
||||||
for (var i = 0, l = events.length; i < l; i++) {
|
const event = events[i].trim();
|
||||||
var event = events[i].trim();
|
const list = this._getEventList(event, true);
|
||||||
var list = this._getEventList(event, true);
|
|
||||||
// TODO: Performance optimization - if we do not have the thisArg specified, do not wrap the callback in additional object (ObserveEntry)
|
// TODO: Performance optimization - if we do not have the thisArg specified, do not wrap the callback in additional object (ObserveEntry)
|
||||||
list.push({
|
list.push({
|
||||||
callback: callback,
|
callback: callback,
|
||||||
@@ -103,19 +78,22 @@ export class Observable implements definition.Observable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeEventListener(eventNames: string, callback?: any, thisArg?: any) {
|
public removeEventListener(eventNames: string, callback?: any, thisArg?: Object) {
|
||||||
if (!types.isString(eventNames)) {
|
if (typeof eventNames !== "string") {
|
||||||
throw new TypeError("Events name(s) must be string.");
|
throw new TypeError("Events name(s) must be string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var events: Array<string> = eventNames.split(",");
|
if (callback && typeof callback !== "function") {
|
||||||
|
throw new TypeError("callback must be function.");
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0, l = events.length; i < l; i++) {
|
const events = eventNames.split(",");
|
||||||
var event = events[i].trim();
|
for (let i = 0, l = events.length; i < l; i++) {
|
||||||
|
const event = events[i].trim();
|
||||||
if (callback) {
|
if (callback) {
|
||||||
var list = this._getEventList(event, false);
|
const list = this._getEventList(event, false);
|
||||||
if (list) {
|
if (list) {
|
||||||
var index = this._indexOfListener(list, callback, thisArg);
|
const index = this._indexOfListener(list, callback, thisArg);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
list.splice(index, 1);
|
list.splice(index, 1);
|
||||||
}
|
}
|
||||||
@@ -131,54 +109,14 @@ export class Observable implements definition.Observable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public notifyPropertyChange(propertyName: string, newValue: any) {
|
public notify<T extends EventData>(data: T) {
|
||||||
this.notify(this._createPropertyChangeData(propertyName, newValue));
|
const observers = this._getEventList(data.eventName);
|
||||||
}
|
|
||||||
|
|
||||||
public set(name: string, value: any) {
|
|
||||||
// TODO: Parameter validation
|
|
||||||
if (this[name] === value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create data for the change
|
|
||||||
var data = this._createPropertyChangeData(name, value);
|
|
||||||
|
|
||||||
this._setCore(data);
|
|
||||||
this.notify(data);
|
|
||||||
|
|
||||||
// TODO: Maybe we need to update source object used in the constructor as well?
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(name: string): any {
|
|
||||||
return this[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
//private disableNotifications = false;
|
|
||||||
private disableNotifications = {};
|
|
||||||
|
|
||||||
public _setCore(data: definition.PropertyChangeData) {
|
|
||||||
this.disableNotifications[data.propertyName] = true;
|
|
||||||
let newValue = WrappedValue.unwrap(data.value);
|
|
||||||
this[data.propertyName] = newValue;
|
|
||||||
delete this.disableNotifications[data.propertyName];
|
|
||||||
}
|
|
||||||
|
|
||||||
public notify<T extends definition.EventData>(data: T) {
|
|
||||||
if (this.disableNotifications[(<any>data).propertyName]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var observers = this._getEventList(data.eventName);
|
|
||||||
if (!observers) {
|
if (!observers) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var i;
|
for (let i = observers.length - 1; i >= 0; i--) {
|
||||||
var entry: ListenerEntry;
|
let entry = observers[i];
|
||||||
var observersLength = observers.length;
|
|
||||||
for (i = observersLength - 1; i >= 0; i--) {
|
|
||||||
entry = observers[i];
|
|
||||||
if (entry.thisArg) {
|
if (entry.thisArg) {
|
||||||
entry.callback.apply(entry.thisArg, [data]);
|
entry.callback.apply(entry.thisArg, [data]);
|
||||||
} else {
|
} else {
|
||||||
@@ -187,11 +125,15 @@ export class Observable implements definition.Observable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public notifyPropertyChange(name: string, newValue: any) {
|
||||||
|
this.notify(this._createPropertyChangeData(name, newValue));
|
||||||
|
}
|
||||||
|
|
||||||
public hasListeners(eventName: string) {
|
public hasListeners(eventName: string) {
|
||||||
return eventName in this._observers;
|
return eventName in this._observers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public _createPropertyChangeData(name: string, value: any): definition.PropertyChangeData {
|
public _createPropertyChangeData(name: string, value: any): PropertyChangeData {
|
||||||
return {
|
return {
|
||||||
eventName: Observable.propertyChangeEvent,
|
eventName: Observable.propertyChangeEvent,
|
||||||
propertyName: name,
|
propertyName: name,
|
||||||
@@ -201,10 +143,10 @@ export class Observable implements definition.Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public _emit(eventNames: string) {
|
public _emit(eventNames: string) {
|
||||||
var events: Array<string> = eventNames.split(",");
|
const events = eventNames.split(",");
|
||||||
|
|
||||||
for (var i = 0, l = events.length; i < l; i++) {
|
for (let i = 0, l = events.length; i < l; i++) {
|
||||||
var event = events[i].trim();
|
const event = events[i].trim();
|
||||||
this.notify({ eventName: event, object: this });
|
this.notify({ eventName: event, object: this });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,7 +156,7 @@ export class Observable implements definition.Observable {
|
|||||||
throw new TypeError("EventName must be valid string.");
|
throw new TypeError("EventName must be valid string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = <Array<ListenerEntry>>this._observers[eventName];
|
let list = <Array<ListenerEntry>>this._observers[eventName];
|
||||||
if (!list && createIfNeeded) {
|
if (!list && createIfNeeded) {
|
||||||
list = [];
|
list = [];
|
||||||
this._observers[eventName] = list;
|
this._observers[eventName] = list;
|
||||||
@@ -223,12 +165,9 @@ export class Observable implements definition.Observable {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _indexOfListener(list: Array<ListenerEntry>, callback: (data: definition.EventData) => void, thisArg?: any): number {
|
private _indexOfListener(list: Array<ListenerEntry>, callback: (data: EventData) => void, thisArg?: any): number {
|
||||||
var i;
|
for (let i = 0; i < list.length; i++) {
|
||||||
var entry: ListenerEntry;
|
const entry = list[i];
|
||||||
|
|
||||||
for (i = 0; i < list.length; i++) {
|
|
||||||
entry = list[i];
|
|
||||||
if (thisArg) {
|
if (thisArg) {
|
||||||
if (entry.callback === callback && entry.thisArg === thisArg) {
|
if (entry.callback === callback && entry.thisArg === thisArg) {
|
||||||
return i;
|
return i;
|
||||||
@@ -243,36 +182,59 @@ export class Observable implements definition.Observable {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public toString(): string {
|
class ObservableFromObject extends Observable {
|
||||||
return this.typeName;
|
public _map: Map<string, Object> = new Map<string, Object>();
|
||||||
|
|
||||||
|
public set(name: string, value: any) {
|
||||||
|
const currentValue = this._map.get(name);
|
||||||
|
if (currentValue === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newValue = WrappedValue.unwrap(value);
|
||||||
|
this._map.set(name, newValue);
|
||||||
|
this.notifyPropertyChange(name, newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPropertiesFromObject(observable: Observable, source: any, recursive?: boolean) {
|
function defineNewProperty(target: ObservableFromObject, propertyName: string): void {
|
||||||
let isRecursive = recursive || false;
|
Object.defineProperty(target, propertyName, {
|
||||||
observable._map = new Map<string, Object>();
|
get: function () {
|
||||||
|
return target._map.get(propertyName);
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
target.set(propertyName, value);
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPropertiesFromObject(observable: ObservableFromObject, source: any, recursive: boolean = false) {
|
||||||
|
let isRecursive = recursive;
|
||||||
for (let prop in source) {
|
for (let prop in source) {
|
||||||
if (source.hasOwnProperty(prop)) {
|
if (source.hasOwnProperty(prop)) {
|
||||||
if (isRecursive) {
|
if (isRecursive) {
|
||||||
if (!Array.isArray(source[prop]) && source[prop] && typeof source[prop] === 'object' && types.getClass(source[prop]) !== 'ObservableArray') {
|
if (!Array.isArray(source[prop]) && source[prop] && typeof source[prop] === 'object' && !(source[prop] instanceof Observable)) {
|
||||||
source[prop] = fromObjectRecursive(source[prop]);
|
source[prop] = fromObjectRecursive(source[prop]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
observable._defineNewProperty(prop);
|
defineNewProperty(observable, prop);
|
||||||
observable.set(prop, source[prop]);
|
observable.set(prop, source[prop]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fromObject(source: any): Observable {
|
export function fromObject(source: any): Observable {
|
||||||
let observable = new Observable();
|
let observable = new ObservableFromObject();
|
||||||
addPropertiesFromObject(observable, source, false);
|
addPropertiesFromObject(observable, source, false);
|
||||||
return observable;
|
return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fromObjectRecursive(source: any): Observable {
|
export function fromObjectRecursive(source: any): Observable {
|
||||||
let observable = new Observable();
|
let observable = new ObservableFromObject();
|
||||||
addPropertiesFromObject(observable, source, true);
|
addPropertiesFromObject(observable, source, true);
|
||||||
return observable;
|
return observable;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { ActivityIndicatorBase, busyProperty, colorProperty } from "./activity-indicator-common";
|
import { ActivityIndicatorBase, busyProperty, colorProperty } from "./activity-indicator-common";
|
||||||
import { ios } from "utils/utils";
|
|
||||||
import { Color } from "color";
|
import { Color } from "color";
|
||||||
|
|
||||||
export * from "./activity-indicator-common";
|
export * from "./activity-indicator-common";
|
||||||
|
|||||||
@@ -1,27 +1,15 @@
|
|||||||
import * as definition from "ui/core/bindable";
|
import * as definition from "ui/core/bindable";
|
||||||
import { Observable, PropertyChangeData } from "data/observable";
|
import { Observable, PropertyChangeData } from "data/observable";
|
||||||
import { unsetValue, DependencyObservable, Property } from "ui/core/dependency-observable";
|
import { unsetValue, DependencyObservable } from "ui/core/dependency-observable";
|
||||||
import { addWeakEventListener, removeWeakEventListener } from "ui/core/weak-event-listener";
|
import { addWeakEventListener, removeWeakEventListener } from "ui/core/weak-event-listener";
|
||||||
import types = require("utils/types");
|
import types = require("utils/types");
|
||||||
import bindingBuilder = require("../builder/binding-builder");
|
import bindingBuilder = require("../builder/binding-builder");
|
||||||
import { ViewBase, isEventOrGesture, bindingContextProperty } from "ui/core/view-base";
|
import { ViewBase, isEventOrGesture, bindingContextProperty } from "ui/core/view-base";
|
||||||
import * as application from "application";
|
import * as application from "application";
|
||||||
import * as polymerExpressions from "js-libs/polymer-expressions";
|
import * as polymerExpressions from "js-libs/polymer-expressions";
|
||||||
import * as specialProperties from "ui/builder/special-properties";
|
|
||||||
import * as utils from "utils/utils";
|
import * as utils from "utils/utils";
|
||||||
|
|
||||||
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories, messageType as traceMessageType } from "trace";
|
import { write as traceWrite, categories as traceCategories, messageType as traceMessageType } from "trace";
|
||||||
|
|
||||||
// let bindingContextProperty = new Property(
|
|
||||||
// "bindingContext",
|
|
||||||
// "Bindable",
|
|
||||||
// new PropertyMetadata(undefined, PropertyMetadataSettings.Inheritable, onBindingContextChanged)
|
|
||||||
// );
|
|
||||||
|
|
||||||
// function onBindingContextChanged(data: DependencyPropertyChangeData) {
|
|
||||||
// let bindable = <Bindable>data.object;
|
|
||||||
// bindable._onBindingContextChanged(data.oldValue, data.newValue);
|
|
||||||
// }
|
|
||||||
|
|
||||||
let contextKey = "context";
|
let contextKey = "context";
|
||||||
// this regex is used to get parameters inside [] for example:
|
// this regex is used to get parameters inside [] for example:
|
||||||
@@ -75,72 +63,72 @@ export class Bindable extends DependencyObservable implements definition.Bindabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateTwoWayBinding(propertyName: string, value: any) {
|
// public _updateTwoWayBinding(propertyName: string, value: any) {
|
||||||
let binding: Binding = this.bindings.get(propertyName);
|
// let binding: Binding = this.bindings.get(propertyName);
|
||||||
if (binding) {
|
// if (binding) {
|
||||||
binding.updateTwoWay(value);
|
// binding.updateTwoWay(value);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public _setCore(data: PropertyChangeData) {
|
|
||||||
super._setCore(data);
|
|
||||||
this._updateTwoWayBinding(data.propertyName, data.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public _onPropertyChanged(property: Property, oldValue: any, newValue: any) {
|
|
||||||
if (traceEnabled) {
|
|
||||||
traceWrite(`${this}._onPropertyChanged(${property.name}, ${oldValue}, ${newValue})`, traceCategories.Binding);
|
|
||||||
}
|
|
||||||
super._onPropertyChanged(property, oldValue, newValue);
|
|
||||||
// if (this instanceof viewModule.View) {
|
|
||||||
// if (property.inheritable && (<viewModule.View>(<any>this))._isInheritedChange() === true) {
|
|
||||||
// return;
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
let binding = this.bindings.get(property.name);
|
// public _setCore(data: PropertyChangeData) {
|
||||||
if (binding && !binding.updating) {
|
// super._setCore(data);
|
||||||
if (binding.options.twoWay) {
|
// this._updateTwoWayBinding(data.propertyName, data.value);
|
||||||
if (traceEnabled) {
|
// }
|
||||||
traceWrite(`${this}._updateTwoWayBinding(${property.name}, ${newValue});` + property.name, traceCategories.Binding);
|
|
||||||
}
|
// public _onPropertyChanged(property: Property, oldValue: any, newValue: any) {
|
||||||
this._updateTwoWayBinding(property.name, newValue);
|
// if (traceEnabled) {
|
||||||
}
|
// traceWrite(`${this}._onPropertyChanged(${property.name}, ${oldValue}, ${newValue})`, traceCategories.Binding);
|
||||||
else {
|
// }
|
||||||
if (traceEnabled) {
|
// super._onPropertyChanged(property, oldValue, newValue);
|
||||||
traceWrite(`${this}.unbind(${property.name});`, traceCategories.Binding);
|
// // if (this instanceof viewModule.View) {
|
||||||
}
|
// // if (property.inheritable && (<viewModule.View>(<any>this))._isInheritedChange() === true) {
|
||||||
this.unbind(property.name);
|
// // return;
|
||||||
}
|
// // }
|
||||||
}
|
// // }
|
||||||
|
|
||||||
|
// let binding = this.bindings.get(property.name);
|
||||||
|
// if (binding && !binding.updating) {
|
||||||
|
// if (binding.options.twoWay) {
|
||||||
|
// if (traceEnabled) {
|
||||||
|
// traceWrite(`${this}._updateTwoWayBinding(${property.name}, ${newValue});` + property.name, traceCategories.Binding);
|
||||||
|
// }
|
||||||
|
// this._updateTwoWayBinding(property.name, newValue);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// if (traceEnabled) {
|
||||||
|
// traceWrite(`${this}.unbind(${property.name});`, traceCategories.Binding);
|
||||||
|
// }
|
||||||
|
// this.unbind(property.name);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public _onBindingContextChanged(oldValue: any, newValue: any) {
|
||||||
|
// let bindingContextBinding = this.bindings.get("bindingContext");
|
||||||
|
// if (bindingContextBinding) {
|
||||||
|
// if (!bindingContextBinding.updating) {
|
||||||
|
// bindingContextBinding.bind(newValue);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let bindingContextSource = this.bindingContext;
|
||||||
|
|
||||||
|
// this.bindings.forEach((binding, index, bindings) => {
|
||||||
|
// if (!binding.updating && binding.sourceIsBindingContext && binding.options.targetProperty !== "bindingContext") {
|
||||||
|
// if (traceEnabled) {
|
||||||
|
// traceWrite(`Binding ${binding.target.get()}.${binding.options.targetProperty} to new context ${bindingContextSource}`, traceCategories.Binding);
|
||||||
|
// }
|
||||||
|
// if (!types.isNullOrUndefined(bindingContextSource)) {
|
||||||
|
// binding.bind(bindingContextSource);
|
||||||
|
// } else {
|
||||||
|
// binding.clearBinding();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public _onBindingContextChanged(oldValue: any, newValue: any) {
|
const emptyArray = [];
|
||||||
let bindingContextBinding = this.bindings.get("bindingContext");
|
|
||||||
if (bindingContextBinding) {
|
|
||||||
if (!bindingContextBinding.updating) {
|
|
||||||
bindingContextBinding.bind(newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let bindingContextSource = this.bindingContext;
|
|
||||||
|
|
||||||
this.bindings.forEach((binding, index, bindings) => {
|
|
||||||
if (!binding.updating && binding.sourceIsBindingContext && binding.options.targetProperty !== "bindingContext") {
|
|
||||||
if (traceEnabled) {
|
|
||||||
traceWrite(`Binding ${binding.target.get()}.${binding.options.targetProperty} to new context ${bindingContextSource}`, traceCategories.Binding);
|
|
||||||
}
|
|
||||||
if (!types.isNullOrUndefined(bindingContextSource)) {
|
|
||||||
binding.bind(bindingContextSource);
|
|
||||||
} else {
|
|
||||||
binding.clearBinding();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let emptyArray = [];
|
|
||||||
function getProperties(property: string): Array<string> {
|
function getProperties(property: string): Array<string> {
|
||||||
let result: Array<string> = emptyArray;
|
let result: Array<string> = emptyArray;
|
||||||
if (property) {
|
if (property) {
|
||||||
@@ -188,13 +176,24 @@ export class Binding {
|
|||||||
if (!this.targetOptions) {
|
if (!this.targetOptions) {
|
||||||
throw new Error(`Invalid property: ${options.targetProperty} for target: ${target}`);
|
throw new Error(`Invalid property: ${options.targetProperty} for target: ${target}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.twoWay) {
|
||||||
|
const target = this.targetOptions.instance.get();
|
||||||
|
if (target instanceof Observable) {
|
||||||
|
target.on(`${this.targetOptions.property}Change`, this.onTargetPropertyChanged, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onTargetPropertyChanged(data: PropertyChangeData): void {
|
||||||
|
this.updateTwoWay(data.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadedHandlerVisualTreeBinding(args) {
|
public loadedHandlerVisualTreeBinding(args) {
|
||||||
let target = args.object;
|
let target = args.object;
|
||||||
target.off("loaded", this.loadedHandlerVisualTreeBinding, this);
|
target.off("loaded", this.loadedHandlerVisualTreeBinding, this);
|
||||||
if (!types.isNullOrUndefined(target.bindingContext)) {
|
if (!types.isNullOrUndefined(target.bindingContext)) {
|
||||||
this.bind(target.bindingContext);
|
this.update(target.bindingContext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -237,25 +236,39 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bindingContextChanged(data: PropertyChangeData): void {
|
private bindingContextChanged(data: PropertyChangeData): void {
|
||||||
let target = this.target.get();
|
const target = this.targetOptions.instance.get();
|
||||||
if (!target) {
|
if (!target) {
|
||||||
this.unbind();
|
this.unbind();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.value) {
|
if (data.value) {
|
||||||
this.bind(data.value);
|
this.update(data.value);
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: Is this correct?
|
||||||
|
// What should happen when bindingContext is null/undefined?
|
||||||
this.clearBinding();
|
this.clearBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: if oneWay - call target.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bind(source: Object): void {
|
public bind(source: any): void {
|
||||||
|
const target = this.targetOptions.instance.get();
|
||||||
|
if (this.sourceIsBindingContext && target instanceof Observable && this.targetOptions.property !== "bindingContext") {
|
||||||
|
target.on("bindingContextChange", this.bindingContextChanged, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private update(source: any): void {
|
||||||
this.clearSource();
|
this.clearSource();
|
||||||
|
|
||||||
source = this.sourceAsObject(source);
|
source = this.sourceAsObject(source);
|
||||||
|
|
||||||
if (!types.isNullOrUndefined(source)) {
|
if (!types.isNullOrUndefined(source)) {
|
||||||
|
// TODO: if oneWay - call target.unbind();
|
||||||
this.source = new WeakRef(source);
|
this.source = new WeakRef(source);
|
||||||
this.sourceOptions = this.resolveOptions(source, this.sourceProperties);
|
this.sourceOptions = this.resolveOptions(source, this.sourceProperties);
|
||||||
|
|
||||||
@@ -263,14 +276,36 @@ export class Binding {
|
|||||||
this.updateTarget(sourceValue);
|
this.updateTarget(sourceValue);
|
||||||
this.addPropertyChangeListeners(this.source, this.sourceProperties);
|
this.addPropertyChangeListeners(this.source, this.sourceProperties);
|
||||||
} else if (!this.sourceIsBindingContext) {
|
} else if (!this.sourceIsBindingContext) {
|
||||||
|
// TODO: if oneWay - call target.unbind();
|
||||||
let sourceValue = this.getSourcePropertyValue();
|
let sourceValue = this.getSourcePropertyValue();
|
||||||
this.updateTarget(sourceValue ? sourceValue : source);
|
this.updateTarget(sourceValue ? sourceValue : source);
|
||||||
} else if (this.sourceIsBindingContext && (source === undefined || source === null)) {
|
|
||||||
this.target.get().off("bindingContextChange", this.bindingContextChanged, this);
|
|
||||||
this.target.get().on("bindingContextChange", this.bindingContextChanged, this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unbind() {
|
||||||
|
const target = this.targetOptions.instance.get();
|
||||||
|
if (target instanceof Observable) {
|
||||||
|
if (this.options.twoWay) {
|
||||||
|
target.off(`${this.targetOptions.property}Change`, this.onTargetPropertyChanged, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sourceIsBindingContext && this.targetOptions.property !== "bindingContext") {
|
||||||
|
target.off("bindingContextChange", this.bindingContextChanged, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.targetOptions) {
|
||||||
|
this.targetOptions = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sourceProperties = undefined;
|
||||||
|
if (!this.source) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearSource();
|
||||||
|
}
|
||||||
|
|
||||||
// Consider returning single {} instead of array for performance.
|
// Consider returning single {} instead of array for performance.
|
||||||
private resolveObjectsAndProperties(source: Object, properties: Array<string>): Array<{ instance: Object; property: string }> {
|
private resolveObjectsAndProperties(source: Object, properties: Array<string>): Array<{ instance: Object; property: string }> {
|
||||||
let result = [];
|
let result = [];
|
||||||
@@ -330,24 +365,6 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unbind() {
|
|
||||||
if (!this.source) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.clearSource();
|
|
||||||
|
|
||||||
let target = this.target.get();
|
|
||||||
if (target) {
|
|
||||||
target.off(`${bindingContextProperty}Change`, this.bindingContextChanged, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.targetOptions) {
|
|
||||||
this.targetOptions = undefined;
|
|
||||||
}
|
|
||||||
this.sourceProperties = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private prepareExpressionForUpdate(): string {
|
private prepareExpressionForUpdate(): string {
|
||||||
// this regex is used to create a valid RegExp object from a string that has some special regex symbols like [,(,$ and so on.
|
// this regex is used to create a valid RegExp object from a string that has some special regex symbols like [,(,$ and so on.
|
||||||
// Basically this method replaces all matches of 'source property' in expression with '$newPropertyValue'.
|
// Basically this method replaces all matches of 'source property' in expression with '$newPropertyValue'.
|
||||||
@@ -361,7 +378,7 @@ export class Binding {
|
|||||||
return resultExp;
|
return resultExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateTwoWay(value: any) {
|
private updateTwoWay(value: any) {
|
||||||
if (this.updating || !this.options.twoWay) {
|
if (this.updating || !this.options.twoWay) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -432,8 +449,8 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onSourcePropertyChanged(data: PropertyChangeData) {
|
public onSourcePropertyChanged(data: PropertyChangeData) {
|
||||||
let sourceProps = this.sourceProperties;
|
const sourceProps = this.sourceProperties;
|
||||||
let sourcePropsLength = sourceProps.length;
|
const sourcePropsLength = sourceProps.length;
|
||||||
let changedPropertyIndex = sourceProps.indexOf(data.propertyName);
|
let changedPropertyIndex = sourceProps.indexOf(data.propertyName);
|
||||||
let parentProps = "";
|
let parentProps = "";
|
||||||
if (changedPropertyIndex > -1) {
|
if (changedPropertyIndex > -1) {
|
||||||
@@ -445,16 +462,16 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.expression) {
|
if (this.options.expression) {
|
||||||
let expressionValue = this._getExpressionValue(this.options.expression, false, undefined);
|
const expressionValue = this._getExpressionValue(this.options.expression, false, undefined);
|
||||||
if (expressionValue instanceof Error) {
|
if (expressionValue instanceof Error) {
|
||||||
traceWrite((<Error>expressionValue).message, traceCategories.Binding, traceMessageType.error);
|
traceWrite(expressionValue.message, traceCategories.Binding, traceMessageType.error);
|
||||||
} else {
|
} else {
|
||||||
this.updateTarget(expressionValue);
|
this.updateTarget(expressionValue);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (changedPropertyIndex > -1) {
|
if (changedPropertyIndex > -1) {
|
||||||
let props = sourceProps.slice(changedPropertyIndex + 1);
|
const props = sourceProps.slice(changedPropertyIndex + 1);
|
||||||
let propsLength = props.length;
|
const propsLength = props.length;
|
||||||
if (propsLength > 0) {
|
if (propsLength > 0) {
|
||||||
let value = data.value;
|
let value = data.value;
|
||||||
for (let i = 0; i < propsLength; i++) {
|
for (let i = 0; i < propsLength; i++) {
|
||||||
@@ -468,15 +485,15 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to do this only if nested objects are used as source and some middle object is changed.
|
// we need to do this only if nested objects are used as source and some middle object has changed.
|
||||||
if (changedPropertyIndex > -1 && changedPropertyIndex < sourcePropsLength - 1) {
|
if (changedPropertyIndex > -1 && changedPropertyIndex < sourcePropsLength - 1) {
|
||||||
var probablyChangedObject = this.propertyChangeListeners.get(parentProps);
|
const probablyChangedObject = this.propertyChangeListeners.get(parentProps);
|
||||||
if (probablyChangedObject &&
|
if (probablyChangedObject &&
|
||||||
probablyChangedObject !== data.object[sourceProps[changedPropertyIndex]]) {
|
probablyChangedObject !== data.object[sourceProps[changedPropertyIndex]]) {
|
||||||
// remove all weakevent listeners after change, because changed object replaces object that is hooked for
|
// remove all weakevent listeners after change, because changed object replaces object that is hooked for
|
||||||
// propertyChange event
|
// propertyChange event
|
||||||
for (let i = sourcePropsLength - 1; i > changedPropertyIndex; i--) {
|
for (let i = sourcePropsLength - 1; i > changedPropertyIndex; i--) {
|
||||||
let prop = "$" + sourceProps.slice(0, i + 1).join("$");
|
const prop = "$" + sourceProps.slice(0, i + 1).join("$");
|
||||||
if (this.propertyChangeListeners.has(prop)) {
|
if (this.propertyChangeListeners.has(prop)) {
|
||||||
removeWeakEventListener(
|
removeWeakEventListener(
|
||||||
this.propertyChangeListeners.get(prop),
|
this.propertyChangeListeners.get(prop),
|
||||||
@@ -487,9 +504,9 @@ export class Binding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let newProps = sourceProps.slice(changedPropertyIndex + 1);
|
const newProps = sourceProps.slice(changedPropertyIndex + 1);
|
||||||
// add new weak event listeners
|
// add new weak event listeners
|
||||||
var newObject = data.object[sourceProps[changedPropertyIndex]]
|
const newObject = data.object[sourceProps[changedPropertyIndex]]
|
||||||
if (!types.isNullOrUndefined(newObject) && typeof newObject === 'object') {
|
if (!types.isNullOrUndefined(newObject) && typeof newObject === 'object') {
|
||||||
this.addPropertyChangeListeners(new WeakRef(newObject), newProps, parentProps);
|
this.addPropertyChangeListeners(new WeakRef(newObject), newProps, parentProps);
|
||||||
}
|
}
|
||||||
@@ -559,7 +576,7 @@ export class Binding {
|
|||||||
|
|
||||||
public clearBinding() {
|
public clearBinding() {
|
||||||
this.clearSource();
|
this.clearSource();
|
||||||
this.updateTarget(undefined);
|
this.updateTarget(unsetValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateTarget(value: any) {
|
private updateTarget(value: any) {
|
||||||
@@ -638,25 +655,19 @@ export class Binding {
|
|||||||
this.updating = true;
|
this.updating = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (optionsInstance instanceof ViewBase &&
|
const isView = optionsInstance instanceof ViewBase
|
||||||
|
if (isView &&
|
||||||
isEventOrGesture(options.property, <any>optionsInstance) &&
|
isEventOrGesture(options.property, <any>optionsInstance) &&
|
||||||
types.isFunction(value)) {
|
types.isFunction(value)) {
|
||||||
// calling off method with null as handler will remove all handlers for options.property event
|
// calling off method with null as handler will remove all handlers for options.property event
|
||||||
optionsInstance.off(options.property, null, optionsInstance.bindingContext);
|
optionsInstance.off(options.property, null, optionsInstance.bindingContext);
|
||||||
optionsInstance.on(options.property, value, optionsInstance.bindingContext);
|
optionsInstance.on(options.property, value, optionsInstance.bindingContext);
|
||||||
} else {
|
} else if (!isView && optionsInstance instanceof Observable) {
|
||||||
let specialSetter = specialProperties.getSpecialPropertySetter(options.property);
|
|
||||||
if (specialSetter) {
|
|
||||||
specialSetter(optionsInstance, value);
|
|
||||||
} else {
|
|
||||||
if (optionsInstance instanceof Observable) {
|
|
||||||
optionsInstance.set(options.property, value);
|
optionsInstance.set(options.property, value);
|
||||||
} else {
|
} else {
|
||||||
optionsInstance[options.property] = value;
|
optionsInstance[options.property] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
traceWrite("Binding error while setting property " + options.property + " of " + optionsInstance + ": " + ex,
|
traceWrite("Binding error while setting property " + options.property + " of " + optionsInstance + ": " + ex,
|
||||||
traceCategories.Binding,
|
traceCategories.Binding,
|
||||||
|
|||||||
@@ -286,8 +286,7 @@ export class DependencyObservable extends Observable implements DependencyObserv
|
|||||||
|
|
||||||
let propName = property.name;
|
let propName = property.name;
|
||||||
if (this.hasListeners(Observable.propertyChangeEvent)) {
|
if (this.hasListeners(Observable.propertyChangeEvent)) {
|
||||||
let changeData = super._createPropertyChangeData(propName, newValue);
|
this.notifyPropertyChange(propName, newValue);
|
||||||
this.notify(changeData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let eventName = property.nameEvent;
|
let eventName = property.nameEvent;
|
||||||
@@ -325,10 +324,6 @@ export class DependencyObservable extends Observable implements DependencyObserv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString(): string {
|
|
||||||
return this.typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _setValueInternal(property: Property, value: any, source: number) {
|
private _setValueInternal(property: Property, value: any, source: number) {
|
||||||
if (value === unsetValue) {
|
if (value === unsetValue) {
|
||||||
this._resetValue(property, source);
|
this._resetValue(property, source);
|
||||||
|
|||||||
@@ -322,8 +322,6 @@ export class InheritedProperty<T extends ViewBase, U> extends Property<T, U> imp
|
|||||||
const key = this.key;
|
const key = this.key;
|
||||||
const defaultValue = options.defaultValue;
|
const defaultValue = options.defaultValue;
|
||||||
|
|
||||||
const eventName = name + "Change";
|
|
||||||
|
|
||||||
const sourceKey = Symbol(name + ":valueSourceKey");
|
const sourceKey = Symbol(name + ":valueSourceKey");
|
||||||
this.sourceKey = sourceKey;
|
this.sourceKey = sourceKey;
|
||||||
|
|
||||||
@@ -360,16 +358,6 @@ export class InheritedProperty<T extends ViewBase, U> extends Property<T, U> imp
|
|||||||
that[sourceKey] = newValueSource;
|
that[sourceKey] = newValueSource;
|
||||||
|
|
||||||
if (currentValue !== newValue) {
|
if (currentValue !== newValue) {
|
||||||
|
|
||||||
if (this.hasListeners(eventName)) {
|
|
||||||
this.notify({
|
|
||||||
eventName: eventName,
|
|
||||||
propertyName: name,
|
|
||||||
object: this,
|
|
||||||
value: unboxedValue
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const reset = newValueSource === ValueSource.Default;
|
const reset = newValueSource === ValueSource.Default;
|
||||||
that.eachChild((child) => {
|
that.eachChild((child) => {
|
||||||
const childValueSource = child[sourceKey] || ValueSource.Default;
|
const childValueSource = child[sourceKey] || ValueSource.Default;
|
||||||
@@ -379,7 +367,7 @@ export class InheritedProperty<T extends ViewBase, U> extends Property<T, U> imp
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (childValueSource <= ValueSource.Inherited) {
|
if (childValueSource <= ValueSource.Inherited) {
|
||||||
setInheritedValue.call(child, child.parent[key]);
|
setInheritedValue.call(child, newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ViewBase as ViewBaseDefinition } from "ui/core/view-base";
|
import { ViewBase as ViewBaseDefinition } from "ui/core/view-base";
|
||||||
import { Observable, EventData } from "data/observable";
|
import { Observable, EventData, PropertyChangeData } from "data/observable";
|
||||||
import { Property, InheritedProperty, Style, clearInheritedProperties, propagateInheritedProperties, resetCSSProperties, applyNativeSetters, resetStyleProperties } from "./properties";
|
import { Property, InheritedProperty, Style, clearInheritedProperties, propagateInheritedProperties, resetCSSProperties, applyNativeSetters, resetStyleProperties } from "./properties";
|
||||||
import { Binding, BindingOptions, Bindable } from "ui/core/bindable";
|
import { Binding, BindingOptions, Bindable } from "ui/core/bindable";
|
||||||
import { isIOS, isAndroid } from "platform";
|
import { isIOS, isAndroid } from "platform";
|
||||||
@@ -9,6 +9,9 @@ import { KeyframeAnimation } from "ui/animation/keyframe-animation";
|
|||||||
|
|
||||||
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories, notifyEvent as traceNotifyEvent, isCategorySet } from "trace";
|
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories, notifyEvent as traceNotifyEvent, isCategorySet } from "trace";
|
||||||
|
|
||||||
|
// TODO: Remove this import!
|
||||||
|
import * as types from "utils/types";
|
||||||
|
|
||||||
import * as ssm from "ui/styling/style-scope";
|
import * as ssm from "ui/styling/style-scope";
|
||||||
let styleScopeModule: typeof ssm;
|
let styleScopeModule: typeof ssm;
|
||||||
function ensureStyleScopeModule() {
|
function ensureStyleScopeModule() {
|
||||||
@@ -46,6 +49,8 @@ export function getEventOrGestureName(name: string): string {
|
|||||||
return name.indexOf("on") === 0 ? name.substr(2, name.length - 2) : name;
|
return name.indexOf("on") === 0 ? name.substr(2, name.length - 2) : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make this instance function so that we dont need public statc tapEvent = "tap"
|
||||||
|
// in controls. They will just override this one and provide their own event support.
|
||||||
export function isEventOrGesture(name: string, view: ViewBaseDefinition): boolean {
|
export function isEventOrGesture(name: string, view: ViewBaseDefinition): boolean {
|
||||||
if (typeof name === "string") {
|
if (typeof name === "string") {
|
||||||
let eventOrGestureName = getEventOrGestureName(name);
|
let eventOrGestureName = getEventOrGestureName(name);
|
||||||
@@ -127,6 +132,10 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
|
|||||||
this._style = new Style(this);
|
this._style = new Style(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get typeName(): string {
|
||||||
|
return types.getClass(this);
|
||||||
|
}
|
||||||
|
|
||||||
get style(): Style {
|
get style(): Style {
|
||||||
return this._style;
|
return this._style;
|
||||||
}
|
}
|
||||||
@@ -348,39 +357,63 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bindings = new Map<string, Binding>();
|
private bindingContextChanged(data: PropertyChangeData): void {
|
||||||
public bind(options: BindingOptions, source: Object = defaultBindingSource): void {
|
this.bindings.get("bindingContext").bind(data.value);
|
||||||
let binding: Binding = this.bindings.get(options.targetProperty);
|
|
||||||
if (binding) {
|
|
||||||
binding.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding = new Binding(this, options);
|
private bindings: Map<string, Binding>;
|
||||||
this.bindings.set(options.targetProperty, binding);
|
private shouldAddHandlerToParentBindingContextChanged: boolean;
|
||||||
|
private bindingContextBoundToParentBindingContextChanged: boolean;
|
||||||
|
|
||||||
|
public bind(options: BindingOptions, source: Object = defaultBindingSource): void {
|
||||||
|
const targetProperty = options.targetProperty;
|
||||||
|
this.unbind(targetProperty);
|
||||||
|
|
||||||
|
if (!this.bindings) {
|
||||||
|
this.bindings = new Map<string, Binding>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const binding = new Binding(this, options);
|
||||||
|
this.bindings.set(targetProperty, binding);
|
||||||
|
|
||||||
let bindingSource = source;
|
let bindingSource = source;
|
||||||
if (bindingSource === defaultBindingSource) {
|
if (bindingSource === defaultBindingSource) {
|
||||||
bindingSource = this.bindingContext;
|
bindingSource = this.bindingContext;
|
||||||
binding.sourceIsBindingContext = true;
|
binding.sourceIsBindingContext = true;
|
||||||
|
if (targetProperty === "bindingContext") {
|
||||||
|
this.bindingContextBoundToParentBindingContextChanged = true;
|
||||||
|
const parent = this.parent;
|
||||||
|
if (parent) {
|
||||||
|
parent.on("bindingContextChange", this.bindingContextChanged, this);
|
||||||
|
} else {
|
||||||
|
this.shouldAddHandlerToParentBindingContextChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!types.isNullOrUndefined(bindingSource)) {
|
|
||||||
binding.bind(bindingSource);
|
binding.bind(bindingSource);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unbind(property: string): void {
|
public unbind(property: string): void {
|
||||||
let binding: Binding = this.bindings.get(property);
|
const bindings = this.bindings;
|
||||||
if (binding) {
|
if (!bindings) {
|
||||||
binding.unbind();
|
return;
|
||||||
this.bindings.delete(property);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateTwoWayBinding(propertyName: string, value: any) {
|
const binding = bindings.get(property);
|
||||||
let binding: Binding = this.bindings.get(propertyName);
|
|
||||||
if (binding) {
|
if (binding) {
|
||||||
binding.updateTwoWay(value);
|
binding.unbind();
|
||||||
|
bindings.delete(property);
|
||||||
|
if (binding.sourceIsBindingContext) {
|
||||||
|
if (property === "bindingContext") {
|
||||||
|
this.shouldAddHandlerToParentBindingContextChanged = false;
|
||||||
|
this.bindingContextBoundToParentBindingContextChanged = false;
|
||||||
|
const parent = this.parent;
|
||||||
|
if (parent) {
|
||||||
|
parent.off("bindingContextChange", this.bindingContextChanged, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,8 +626,14 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
|
|||||||
public _parentChanged(oldParent: ViewBase): void {
|
public _parentChanged(oldParent: ViewBase): void {
|
||||||
//Overridden
|
//Overridden
|
||||||
if (oldParent) {
|
if (oldParent) {
|
||||||
// Move these method in property class.
|
|
||||||
clearInheritedProperties(this);
|
clearInheritedProperties(this);
|
||||||
|
if (this.bindingContextBoundToParentBindingContextChanged) {
|
||||||
|
oldParent.parent.off("bindingContextChange", this.bindingContextChanged, this);
|
||||||
|
}
|
||||||
|
} else if (this.shouldAddHandlerToParentBindingContextChanged) {
|
||||||
|
const parent = this.parent;
|
||||||
|
parent.on("bindingContextChange", this.bindingContextChanged, this);
|
||||||
|
this.bindings.get("bindingContext").bind(parent.bindingContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
tns-core-modules/ui/definitions.d.ts
vendored
5
tns-core-modules/ui/definitions.d.ts
vendored
@@ -54,6 +54,11 @@ declare module "ui/core/view-base" {
|
|||||||
public nativeView: any;
|
public nativeView: any;
|
||||||
public bindingContext: any;
|
public bindingContext: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the constructor function for this instance. E.g. for a Button class this will return "Button".
|
||||||
|
*/
|
||||||
|
public typeName: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the parent view. This property is read-only.
|
* Gets the parent view. This property is read-only.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export class Progress extends ProgressBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get [backgroundColorProperty.native](): UIColor {
|
get [backgroundColorProperty.native](): number {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
set [backgroundColorProperty.native](value: Color) {
|
set [backgroundColorProperty.native](value: Color) {
|
||||||
@@ -73,7 +73,7 @@ export class Progress extends ProgressBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get [backgroundInternalProperty.native](): UIColor {
|
get [backgroundInternalProperty.native](): number {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
set [backgroundInternalProperty.native](value: Color) {
|
set [backgroundInternalProperty.native](value: Color) {
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ export class ProxyViewContainer extends LayoutBase implements ProxyViewContainer
|
|||||||
* Register/unregister existing children with the parent layout.
|
* Register/unregister existing children with the parent layout.
|
||||||
*/
|
*/
|
||||||
public _parentChanged(oldParent: View): void {
|
public _parentChanged(oldParent: View): void {
|
||||||
|
// call super in order to execute base logic like clear inherited properties, etc.
|
||||||
|
super._parentChanged(oldParent);
|
||||||
const addingToParent = this.parent && !oldParent;
|
const addingToParent = this.parent && !oldParent;
|
||||||
const newLayout = <LayoutBase>this.parent;
|
const newLayout = <LayoutBase>this.parent;
|
||||||
const oldLayout = <LayoutBase>oldParent;
|
const oldLayout = <LayoutBase>oldParent;
|
||||||
|
|||||||
Reference in New Issue
Block a user