feat(change_detection): request a change detection check when an event happens
Closes #3679
This commit is contained in:
@ -72,9 +72,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
return res;
|
||||
}
|
||||
|
||||
handleEventInternal(eventName: string, elIndex: number, locals: Locals): boolean {
|
||||
return false;
|
||||
}
|
||||
handleEventInternal(eventName: string, elIndex: number, locals: Locals): boolean { return false; }
|
||||
|
||||
detectChanges(): void { this.runDetectChanges(false); }
|
||||
|
||||
|
@ -118,8 +118,9 @@ export class BindingRecord {
|
||||
}
|
||||
|
||||
static createForHostEvent(ast: AST, eventName: string,
|
||||
directiveIndex: DirectiveIndex): BindingRecord {
|
||||
directiveRecord: DirectiveRecord): BindingRecord {
|
||||
var directiveIndex = directiveRecord.directiveIndex;
|
||||
return new BindingRecord(EVENT, directiveIndex, ast, directiveIndex.elementIndex, null, null,
|
||||
eventName, null, null, null);
|
||||
eventName, null, null, directiveRecord);
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ export class ChangeDetectorJITGenerator {
|
||||
if (this.eventBindings.length > 0) {
|
||||
var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join("\n");
|
||||
return `
|
||||
${this._typeName}.prototype.handleEvent = function(eventName, elIndex, locals) {
|
||||
${this._typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) {
|
||||
var ${this._names.getPreventDefaultAccesor()} = false;
|
||||
${this._names.genInitEventLocals()}
|
||||
${handlers}
|
||||
@ -106,13 +106,23 @@ export class ChangeDetectorJITGenerator {
|
||||
_genEventBindingEval(eb: EventBinding, r: ProtoRecord): string {
|
||||
if (r.lastInBinding) {
|
||||
var evalRecord = this._logic.genEventBindingEvalValue(eb, r);
|
||||
var markPath = this._genMarkPathToRootAsCheckOnce(r);
|
||||
var prevDefault = this._genUpdatePreventDefault(eb, r);
|
||||
return `${evalRecord}\n${prevDefault}`;
|
||||
return `${evalRecord}\n${markPath}\n${prevDefault}`;
|
||||
} else {
|
||||
return this._logic.genEventBindingEvalValue(eb, r);
|
||||
}
|
||||
}
|
||||
|
||||
_genMarkPathToRootAsCheckOnce(r: ProtoRecord): string {
|
||||
var br = r.bindingRecord;
|
||||
if (br.isOnPushChangeDetection()) {
|
||||
return `${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markPathToRootAsCheckOnce();`;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
_genUpdatePreventDefault(eb: EventBinding, r: ProtoRecord): string {
|
||||
var local = this._names.getEventLocalName(eb, r.selfIndex);
|
||||
return `if (${local} === false) { ${this._names.getPreventDefaultAccesor()} = true};`;
|
||||
|
@ -53,6 +53,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
var proto = eb.records[i];
|
||||
var res = this._calculateCurrValue(proto, values, locals);
|
||||
if (proto.lastInBinding) {
|
||||
this._markPathAsCheckOnce(proto);
|
||||
return res;
|
||||
} else {
|
||||
this._writeSelf(proto, res, values);
|
||||
@ -62,6 +63,13 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
||||
throw new BaseException("Cannot be reached");
|
||||
}
|
||||
|
||||
_markPathAsCheckOnce(proto: ProtoRecord): void {
|
||||
if (proto.bindingRecord.isOnPushChangeDetection()) {
|
||||
var dir = proto.bindingRecord.directiveRecord;
|
||||
this._getDetectorFor(dir.directiveIndex).markPathToRootAsCheckOnce();
|
||||
}
|
||||
}
|
||||
|
||||
_matchingEventBindings(eventName: string, elIndex: number): EventBinding[] {
|
||||
return ListWrapper.filter(this.eventBindings,
|
||||
eb => eb.eventName == eventName && eb.elIndex === elIndex);
|
||||
|
@ -57,8 +57,7 @@ export class BindingRecordsCreator {
|
||||
var directiveMetadata = allDirectiveMetadatas[dir.directiveIndex];
|
||||
var dirRecord = this._getDirectiveRecord(boundElementIndex, i, directiveMetadata);
|
||||
dir.eventBindings.forEach(heb => {
|
||||
res.push(
|
||||
BindingRecord.createForHostEvent(heb.source, heb.fullName, dirRecord.directiveIndex));
|
||||
res.push(BindingRecord.createForHostEvent(heb.source, heb.fullName, dirRecord));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -183,13 +183,23 @@ class _CodegenState {
|
||||
String _genEventBindingEval(EventBinding eb, ProtoRecord r){
|
||||
if (r.lastInBinding) {
|
||||
var evalRecord = _logic.genEventBindingEvalValue(eb, r);
|
||||
var markPath = _genMarkPathToRootAsCheckOnce(r);
|
||||
var prevDefault = _genUpdatePreventDefault(eb, r);
|
||||
return "${evalRecord}\n${prevDefault}";
|
||||
return "${evalRecord}\n${markPath}\n${prevDefault}";
|
||||
} else {
|
||||
return _logic.genEventBindingEvalValue(eb, r);
|
||||
}
|
||||
}
|
||||
|
||||
String _genMarkPathToRootAsCheckOnce(ProtoRecord r) {
|
||||
var br = r.bindingRecord;
|
||||
if (br.isOnPushChangeDetection()) {
|
||||
return "${_names.getDetectorName(br.directiveRecord.directiveIndex)}.markPathToRootAsCheckOnce();";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
String _genUpdatePreventDefault(EventBinding eb, ProtoRecord r) {
|
||||
var local = this._names.getEventLocalName(eb, r.selfIndex);
|
||||
return """if (${local} == false) { ${_names.getPreventDefaultAccesor()} = true; }""";
|
||||
|
Reference in New Issue
Block a user