feat(EventManager): implement the EventManager
This commit is contained in:
@ -497,8 +497,7 @@ export class ElementInjector extends TreeNode {
|
||||
if (isPresent(this._eventCallbacks)) {
|
||||
var callback = MapWrapper.get(this._eventCallbacks, dep.eventEmitterName);
|
||||
if (isPresent(callback)) {
|
||||
var locals = MapWrapper.create();
|
||||
return ProtoView.buildInnerCallback(callback, view, locals);
|
||||
return ProtoView.buildInnerCallback(callback, view);
|
||||
}
|
||||
}
|
||||
return (_) => {};
|
||||
|
34
modules/angular2/src/core/compiler/view.js
vendored
34
modules/angular2/src/core/compiler/view.js
vendored
@ -16,6 +16,7 @@ import {Content} from './shadow_dom_emulation/content_tag';
|
||||
import {LightDom, DestinationLightDom} from './shadow_dom_emulation/light_dom';
|
||||
import {ShadowDomStrategy} from './shadow_dom_strategy';
|
||||
import {ViewPool} from './view_pool';
|
||||
import {EventManager} from 'angular2/src/core/events/event_manager';
|
||||
|
||||
const NG_BINDING_CLASS = 'ng-binding';
|
||||
const NG_BINDING_CLASS_SELECTOR = '.ng-binding';
|
||||
@ -294,19 +295,19 @@ export class ProtoView {
|
||||
}
|
||||
|
||||
// TODO(rado): hostElementInjector should be moved to hydrate phase.
|
||||
instantiate(hostElementInjector: ElementInjector):View {
|
||||
if (this._viewPool.length() == 0) this._preFillPool(hostElementInjector);
|
||||
instantiate(hostElementInjector: ElementInjector, eventManager: EventManager):View {
|
||||
if (this._viewPool.length() == 0) this._preFillPool(hostElementInjector, eventManager);
|
||||
var view = this._viewPool.pop();
|
||||
return isPresent(view) ? view : this._instantiate(hostElementInjector);
|
||||
return isPresent(view) ? view : this._instantiate(hostElementInjector, eventManager);
|
||||
}
|
||||
|
||||
_preFillPool(hostElementInjector: ElementInjector) {
|
||||
_preFillPool(hostElementInjector: ElementInjector, eventManager: EventManager) {
|
||||
for (var i = 0; i < VIEW_POOL_PREFILL; i++) {
|
||||
this._viewPool.push(this._instantiate(hostElementInjector));
|
||||
this._viewPool.push(this._instantiate(hostElementInjector, eventManager));
|
||||
}
|
||||
}
|
||||
|
||||
_instantiate(hostElementInjector: ElementInjector): View {
|
||||
_instantiate(hostElementInjector: ElementInjector, eventManager: EventManager): View {
|
||||
var rootElementClone = this.instantiateInPlace ? this.element : DOM.clone(this.element);
|
||||
var elementsWithBindingsDynamic;
|
||||
if (this.isTemplateElement) {
|
||||
@ -387,7 +388,7 @@ export class ProtoView {
|
||||
var bindingPropagationConfig = null;
|
||||
if (isPresent(binder.componentDirective)) {
|
||||
var strategy = this.shadowDomStrategy;
|
||||
var childView = binder.nestedProtoView.instantiate(elementInjector);
|
||||
var childView = binder.nestedProtoView.instantiate(elementInjector, eventManager);
|
||||
view.changeDetector.addChild(childView.changeDetector);
|
||||
|
||||
lightDom = strategy.constructLightDom(view, childView, element);
|
||||
@ -402,7 +403,8 @@ export class ProtoView {
|
||||
var viewPort = null;
|
||||
if (isPresent(binder.templateDirective)) {
|
||||
var destLightDom = this._directParentElementLightDom(protoElementInjector, preBuiltObjects);
|
||||
viewPort = new ViewPort(view, element, binder.nestedProtoView, elementInjector, destLightDom);
|
||||
viewPort = new ViewPort(view, element, binder.nestedProtoView, elementInjector,
|
||||
eventManager, destLightDom);
|
||||
ListWrapper.push(viewPorts, viewPort);
|
||||
}
|
||||
|
||||
@ -416,7 +418,8 @@ export class ProtoView {
|
||||
if (isPresent(binder.events)) {
|
||||
MapWrapper.forEach(binder.events, (expr, eventName) => {
|
||||
if (isBlank(elementInjector) || !elementInjector.hasEventEmitter(eventName)) {
|
||||
ProtoView._addNativeEventListener(element, eventName, expr, view);
|
||||
var handler = ProtoView.buildInnerCallback(expr, view);
|
||||
eventManager.addEventListener(element, eventName, handler);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -432,24 +435,15 @@ export class ProtoView {
|
||||
this._viewPool.push(view);
|
||||
}
|
||||
|
||||
static _addNativeEventListener(element: Element, eventName: string, expr: AST, view: View) {
|
||||
static buildInnerCallback(expr:AST, view:View) {
|
||||
var locals = MapWrapper.create();
|
||||
var innerCallback = ProtoView.buildInnerCallback(expr, view, locals);
|
||||
DOM.on(element, eventName, (event) => {
|
||||
if (event.target === element) {
|
||||
innerCallback(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static buildInnerCallback(expr:AST, view:View, locals: Map) {
|
||||
return (event) => {
|
||||
// Most of the time the event will be fired only when the view is
|
||||
// in the live document. However, in a rare circumstance the
|
||||
// view might get dehydrated, in between the event queuing up and
|
||||
// firing.
|
||||
if (view.hydrated()) {
|
||||
MapWrapper.set(locals, `$event`, event);
|
||||
MapWrapper.set(locals, '$event', event);
|
||||
var context = new ContextWithVariableBindings(view.context, locals);
|
||||
expr.eval(context);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import {BaseException} from 'angular2/src/facade/lang';
|
||||
import {Injector} from 'angular2/di';
|
||||
import {ElementInjector} from 'angular2/src/core/compiler/element_injector';
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {EventManager} from 'angular2/src/core/events/event_manager';
|
||||
|
||||
export class ViewPort {
|
||||
parentView: View;
|
||||
@ -12,12 +13,13 @@ export class ViewPort {
|
||||
defaultProtoView: ProtoView;
|
||||
_views: List<View>;
|
||||
_lightDom: any;
|
||||
_eventManager: EventManager;
|
||||
elementInjector: ElementInjector;
|
||||
appInjector: Injector;
|
||||
hostElementInjector: ElementInjector;
|
||||
|
||||
constructor(parentView: View, templateElement: Element, defaultProtoView: ProtoView,
|
||||
elementInjector: ElementInjector, lightDom = null) {
|
||||
elementInjector: ElementInjector, eventManager: EventManager, lightDom = null) {
|
||||
this.parentView = parentView;
|
||||
this.templateElement = templateElement;
|
||||
this.defaultProtoView = defaultProtoView;
|
||||
@ -28,6 +30,7 @@ export class ViewPort {
|
||||
this._views = [];
|
||||
this.appInjector = null;
|
||||
this.hostElementInjector = null;
|
||||
this._eventManager = eventManager;
|
||||
}
|
||||
|
||||
hydrate(appInjector: Injector, hostElementInjector: ElementInjector) {
|
||||
@ -70,7 +73,7 @@ export class ViewPort {
|
||||
if (!this.hydrated()) throw new BaseException(
|
||||
'Cannot create views on a dehydrated view port');
|
||||
// TODO(rado): replace with viewFactory.
|
||||
var newView = this.defaultProtoView.instantiate(this.hostElementInjector);
|
||||
var newView = this.defaultProtoView.instantiate(this.hostElementInjector, this._eventManager);
|
||||
newView.hydrate(this.appInjector, this.hostElementInjector, this.parentView.context);
|
||||
return this.insert(newView, atIndex);
|
||||
}
|
||||
|
Reference in New Issue
Block a user