Skip to content

Commit 5d022b0

Browse files
committed
Attach events and support (tap)=... syntax in templates.
1 parent 3811bc0 commit 5d022b0

File tree

2 files changed

+56
-13
lines changed

2 files changed

+56
-13
lines changed

ng-sample/src/main-page.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import {nativeScriptBootstrap} from 'nativescript-angular/application';
1515
template: `
1616
<StackLayout orientation='vertical'>
1717
<Label text='Name' fontSize='32' verticalAlignment='center' padding='20'></Label>
18-
<TextField text='John' fontSize='32' padding='20'></TextField>
19-
<Button [text]='buttonText'></Button>
18+
<TextField #nameText text='John' fontSize='32' padding='20'></TextField>
19+
<Button [text]='buttonText' (tap)='onButtonTap($event)'></Button>
2020
</StackLayout>
2121
`,
2222
directives: []
@@ -27,6 +27,10 @@ class MainPage {
2727
constructor() {
2828
this.buttonText = 'Tap me, baby, one more time!'
2929
}
30+
31+
onButtonTap($event) {
32+
console.log('onButtonTap event ' + $event);
33+
}
3034
}
3135

3236
//TODO: move to an angular init module/base page class

src/nativescript-angular/renderer.ts

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import {View} from 'ui/core/view';
2+
import {Observable, EventData} from 'data/observable';
23
import {Injectable} from 'angular2/angular2';
34
import {MapWrapper} from 'angular2/src/facade/collection';
45
import {DomProtoView, resolveInternalDomProtoView} from 'angular2/src/render/dom/view/proto_view';
56
import {Renderer, RenderElementRef, RenderProtoViewRef, RenderViewRef, EventDispatcher} from 'angular2/src/render/api';
7+
import {AST} from 'angular2/src/change_detection/parser/ast';
68
import {NG_BINDING_CLASS} from 'angular2/src/render/dom/util';
79
import {DOM} from 'angular2/src/dom/dom_adapter';
810
import {topmost} from 'ui/frame';
@@ -13,6 +15,8 @@ import {Label} from 'ui/label';
1315
import {TextField} from 'ui/text-field';
1416

1517
export class NativeScriptView {
18+
public eventDispatcher: EventDispatcher;
19+
1620
constructor(public proto: DomProtoView,
1721
public rootChildElements,
1822
public boundElements: Array<ViewNode>,
@@ -36,6 +40,8 @@ interface ViewClass {
3640
new(): View
3741
}
3842

43+
type EventHandler = (args: EventData) => void;
44+
3945
export class ViewNode {
4046
//TODO: move element registration and imports to a new module
4147
private static allowedElements: Map<string, ViewClass> = new Map<string, ViewClass>([
@@ -45,6 +51,8 @@ export class ViewNode {
4551
["label", Label]
4652
]);
4753

54+
private eventListeners: Map<string, EventHandler> = new Map<string, EventHandler>();
55+
4856
private ui: View;
4957
private _parentView: View;
5058
private _attachedToView: boolean = false;
@@ -102,6 +110,7 @@ export class ViewNode {
102110

103111
if ((<any>this.parentView)._addChildFromBuilder) {
104112
(<any>this.parentView)._addChildFromBuilder(this.viewName, this.ui);
113+
this.attachUIEvents();
105114
} else {
106115
throw new Error("Parent view can't have children! " + this._parentView);
107116
}
@@ -129,6 +138,13 @@ export class ViewNode {
129138
}
130139
}
131140

141+
private attachUIEvents() {
142+
this.eventListeners.forEach((callback, eventName) => {
143+
console.log('Attaching event listener for: ' + eventName);
144+
this.ui.addEventListener(eventName, callback);
145+
});
146+
}
147+
132148
public insertChildAt(index: number, childNode: ViewNode) {
133149
this.children[index] = childNode;
134150
childNode.parentNode = this;
@@ -139,15 +155,20 @@ export class ViewNode {
139155

140156
setProperty(name: string, value: any) {
141157
console.log(this.viewName + ' setProperty ' + name + ' ' + value);
142-
//this.ui._setValue(name, value);
143158
if (this.ui) {
144-
//var page = topmost().currentPage;
145-
//var button = <Button> page.content;
146-
//(<Button>this.ui).text = value;
147159
console.log('actual setProperty ');
148160
this.ui[name] = value;
149161
}
150162
}
163+
164+
createEventListener(view: NativeScriptView, bindingIndex: number, eventName: string, eventLocals: AST) {
165+
console.log('createEventListener ' + this.viewName + ' ' + eventName + ' ' + eventLocals);
166+
this.eventListeners.set(eventName, (args: EventData) => {
167+
var locals = new Map<string, any>();
168+
locals.set('$event', args);
169+
view.eventDispatcher.dispatchEvent(bindingIndex, eventName, locals);
170+
});
171+
}
151172
}
152173

153174
@Injectable()
@@ -219,17 +240,22 @@ export class NativeScriptRenderer extends Renderer {
219240
var element = view.boundElements[location.boundElementIndex];
220241
element.setProperty(propertyName, propertyValue);
221242
}
243+
244+
/**
245+
* Calls a method on an element.
246+
*/
247+
invokeElementMethod(location: RenderElementRef, methodName: string, args: List<any>) {
248+
console.log("NativeScriptRenderer.invokeElementMethod " + methodName + " " + args);
249+
}
222250

223-
callAction(viewRef: RenderViewRef, elementIndex: number, actionExpression: string, actionArgs: any) {
224-
console.log("NativeScriptRenderer.callAction ");
225-
}
226-
227-
setText(viewRef: RenderViewRef, textNodeIndex: number, text: string) {
228-
console.log("NativeScriptRenderer.setText ");
229-
}
251+
setText(viewRef: RenderViewRef, textNodeIndex: number, text: string) {
252+
console.log("NativeScriptRenderer.setText ");
253+
}
230254

231255
setEventDispatcher(viewRef: RenderViewRef, dispatcher: EventDispatcher) {
232256
console.log("NativeScriptRenderer.setEventDispatcher ");
257+
var view = (<NativeScriptViewRef>viewRef).resolveView();
258+
view.eventDispatcher = dispatcher;
233259
}
234260

235261
_createView(proto: DomProtoView, isRoot = false): NativeScriptView {
@@ -249,6 +275,19 @@ export class NativeScriptRenderer extends Renderer {
249275
var boundTextNodes = this._createBoundTextNodes(proto, boundElements);
250276
var view = new NativeScriptView(proto, nativeElements, boundElements, boundTextNodes);
251277

278+
var binders = proto.elementBinders;
279+
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
280+
var binder = binders[binderIdx];
281+
var viewNode = boundElements[binderIdx];
282+
283+
// events
284+
if (binder.eventLocals != null && binder.localEvents != null) {
285+
for (var i = 0; i < binder.localEvents.length; i++) {
286+
viewNode.createEventListener(view, binderIdx, binder.localEvents[i].name, binder.eventLocals);
287+
}
288+
}
289+
}
290+
252291
return view;
253292
}
254293

0 commit comments

Comments
 (0)