Skip to content

Commit 3b944e1

Browse files
committed
Initial prototype of Observable object
1 parent 3fcb0e8 commit 3b944e1

File tree

8 files changed

+179
-2
lines changed

8 files changed

+179
-2
lines changed

BCL.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@
152152
<TypeScriptCompile Include="text\text.ios.ts">
153153
<DependentUpon>text.d.ts</DependentUpon>
154154
</TypeScriptCompile>
155+
<TypeScriptCompile Include="ui\core\proxy.ts" />
156+
<TypeScriptCompile Include="ui\text-view\text-view.android.ts">
157+
<DependentUpon>text-view.d.ts</DependentUpon>
158+
</TypeScriptCompile>
159+
<TypeScriptCompile Include="ui\text-view\text-view.common.ts" />
160+
<TypeScriptCompile Include="ui\text-view\text-view.d.ts" />
161+
<TypeScriptCompile Include="ui\text-view\text-view.ios.ts">
162+
<DependentUpon>text-view.d.ts</DependentUpon>
163+
</TypeScriptCompile>
155164
<TypeScriptCompile Include="utils\module-merge.ts" />
156165
<TypeScriptCompile Include="utils\utils_android.ts" />
157166
<TypeScriptCompile Include="utils\utils_ios.ts" />

ui/core/observable.ts

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,112 @@
1-

1+
export enum ChangePhase {
2+
Changing,
3+
Changed
4+
}
5+
6+
export interface ChangeData {
7+
eventName: string;
8+
sender: Observable;
9+
phase?: ChangePhase;
10+
}
11+
12+
export interface PropertyChangeData extends ChangeData {
13+
propertyName: string;
14+
oldValue: any;
15+
newValue: any;
16+
cancel?: boolean;
17+
}
18+
19+
export class Observable {
20+
public static propertyChangeEvent = "propertyChange";
21+
private _observers = {};
22+
23+
// true to track the Changing phase, false otherwise
24+
private _trackChanging = false;
25+
26+
public bind(eventName: string, callback: (data: ChangeData) => void) {
27+
this.verifyCallback(callback);
28+
var list = this.getEventList(eventName, true);
29+
list.push(callback);
30+
}
31+
32+
public setProperty(name: string, value: any) {
33+
// TODO: Parameter validation
34+
35+
if (!(name in this._observers)) {
36+
// no observers to notify for the PropertyChange event
37+
return;
38+
}
39+
40+
// create data for the change
41+
var data: PropertyChangeData = {
42+
eventName: Observable.propertyChangeEvent,
43+
propertyName: name,
44+
sender: this,
45+
oldValue: this[name],
46+
newValue: value,
47+
cancel: false
48+
};
49+
50+
if (this._trackChanging) {
51+
data.phase = ChangePhase.Changing;
52+
this.notifyObservers(data);
53+
if (data.cancel) {
54+
// change is canceled by an observer
55+
// TODO: define some priority, e.g. if someone cancels the change should others be able to override this cancelation?
56+
return;
57+
}
58+
}
59+
60+
data.phase = ChangePhase.Changed;
61+
this.notifyObservers(data);
62+
63+
this.setPropertyCore(data);
64+
}
65+
66+
public getProperty(name: string): any {
67+
return this[name];
68+
}
69+
70+
/**
71+
* This method is intended to be overriden by inheritors to specify additional
72+
*/
73+
public setPropertyCore(data: PropertyChangeData) {
74+
// get the new value from the data since some observer may have it modified - e.g. validation scenario
75+
this[data.eventName] = data.newValue;
76+
}
77+
78+
private getEventList(eventName: string, createIfNeeded?: boolean): Array<(data: ChangeData) => void> {
79+
if (!eventName) {
80+
throw new TypeError("EventName must be valid string.");
81+
}
82+
83+
var list = <Array<(data: ChangeData) => void>>this._observers[eventName];
84+
if (!list && createIfNeeded) {
85+
list = new Array<(data: ChangeData) => void>();
86+
this._observers[eventName] = list;
87+
}
88+
89+
return list;
90+
}
91+
92+
private verifyCallback(callback: any) {
93+
if (!callback || typeof callback !== "function") {
94+
throw new TypeError("Callback must be a valid function.");
95+
}
96+
}
97+
98+
// The method will return true if the change is accepted, false otherwise
99+
private notifyObservers(data: ChangeData) {
100+
var observers = this.getEventList(data.eventName);
101+
if (!observers) {
102+
return;
103+
}
104+
105+
var i,
106+
callback;
107+
for (i = 0; i < observers.length; i++) {
108+
callback = observers[i];
109+
callback(data);
110+
}
111+
}
112+
}

ui/core/proxy.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import observable = require("ui/core/observable");
2+
3+
export class ProxyObject extends observable.Observable {
4+
public setPropertyCore(data: observable.PropertyChangeData) {
5+
super.setPropertyCore(data);
6+
this.setNativeProperty(data);
7+
}
8+
9+
public setNativeProperty(data: observable.PropertyChangeData) {
10+
// TODO:
11+
}
12+
}

ui/core/view.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-

1+
import proxy = require("ui/core/proxy");
2+
3+
export class View extends proxy.ProxyObject {
4+
5+
}

ui/text-view/text-view.android.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import observable = require("ui/core/observable");
2+
import view = require("ui/core/view");
3+
4+
export class TextView extends view.View {
5+
public android: android.widget.TextView;
6+
7+
get text(): string {
8+
if (this.android) {
9+
return this.android.getText().toString();
10+
}
11+
12+
return undefined;
13+
}
14+
set text(value: string) {
15+
16+
}
17+
18+
public setNativeProperty(data: observable.PropertyChangeData) {
19+
// TODO:
20+
}
21+
}

ui/text-view/text-view.common.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import observable = require("ui/core/observable");
2+
import view = require("ui/core/view");
3+
4+
export class TextView extends view.View {
5+
public static textProperty = "text";
6+
7+
get text(): string {
8+
return this.getProperty(TextView.textProperty);
9+
}
10+
11+
public setNativeProperty(data: observable.PropertyChangeData) {
12+
// TODO:
13+
}
14+
}

ui/text-view/text-view.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+


ui/text-view/text-view.ios.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import view = require("ui/core/view");
2+
3+
export class TextView extends view.View {
4+
5+
}

0 commit comments

Comments
 (0)