feat(dart/transform): Add onInit and onCheck hooks in Dart

Implement `onInit` and `onCheck` hooks in pre-generated Dart change
detectors. This mirrors the changes made to the JIT change detector in
c39c8ebcd0.
This commit is contained in:
Tim Blasi 2015-06-09 15:39:48 -07:00
parent 633cf63682
commit 17c6d6a92d
3 changed files with 51 additions and 18 deletions

View File

@ -236,7 +236,7 @@ export class ChangeDetectorJITGenerator {
} else {
rec = this._genReferenceCheck(r);
}
return `${rec}${this._genLastInDirective(r)}`;
return `${rec}${this._maybeGenLastInDirective(r)}`;
}
_genDirectiveLifecycle(r: ProtoRecord) {
@ -419,7 +419,7 @@ export class ChangeDetectorJITGenerator {
`;
}
_genLastInDirective(r: ProtoRecord): string {
_maybeGenLastInDirective(r: ProtoRecord): string {
if (!r.lastInDirective) return "";
return `
${CHANGES_LOCAL} = null;

View File

@ -7,6 +7,7 @@ import 'package:angular2/src/change_detection/directive_record.dart';
import 'package:angular2/src/change_detection/interfaces.dart';
import 'package:angular2/src/change_detection/proto_change_detector.dart';
import 'package:angular2/src/change_detection/proto_record.dart';
import 'package:angular2/src/facade/lang.dart' show BaseException;
/// Responsible for generating change detector classes for Angular 2.
///
@ -99,6 +100,7 @@ class _CodegenState {
final $_GEN_PREFIX.List<$_GEN_PREFIX.DirectiveRecord>
$_DIRECTIVES_ACCESSOR;
dynamic $_LOCALS_ACCESSOR = null;
dynamic $_ALREADY_CHECKED_ACCESSOR = false;
${_allFields().map((f) {
if (f == _CONTEXT_ACCESSOR) {
return '$_contextTypeName $f = null;';
@ -124,6 +126,8 @@ class _CodegenState {
context = $_CONTEXT_ACCESSOR;
${_records.map(_genRecord).join('')}
$_ALREADY_CHECKED_ACCESSOR = true;
}
void callOnAllChangesDone() {
@ -136,6 +140,7 @@ class _CodegenState {
$_LOCALS_ACCESSOR = locals;
${_genHydrateDirectives()}
${_genHydrateDetectors()}
$_ALREADY_CHECKED_ACCESSOR = false;
}
void dehydrate() {
@ -234,10 +239,26 @@ class _CodegenState {
_changeNames.map((name) => 'var $name = false;').join('');
String _genRecord(ProtoRecord r) {
if (r.mode == RECORD_TYPE_PIPE || r.mode == RECORD_TYPE_BINDING_PIPE) {
return _genPipeCheck(r);
var rec = null;
if (r.isLifeCycleRecord()) {
rec = _genDirectiveLifecycle(r);
} else if (r.isPipeRecord()) {
rec = _genPipeCheck(r);
} else {
return _genReferenceCheck(r);
rec = _genReferenceCheck(r);
}
return '$rec${_maybeGenLastInDirective(r)}';
}
String _genDirectiveLifecycle(ProtoRecord r) {
if (r.name == 'onCheck') {
return _genOnCheck(r);
} else if (r.name == 'onInit') {
return _genOnInit(r);
} else if (r.name == 'onChange') {
return _genOnChange(r);
} else {
throw new BaseException("Unknown lifecycle event '${r.name}'");
}
}
@ -269,7 +290,6 @@ class _CodegenState {
${_genAddToChanges(r)}
$oldValue = $newValue;
}
${_genLastInDirective(r)}
''';
}
@ -287,7 +307,6 @@ class _CodegenState {
${_genAddToChanges(r)}
$oldValue = $newValue;
}
${_genLastInDirective(r)}
''';
if (r.isPureFunction()) {
// Add an "if changed guard"
@ -414,24 +433,32 @@ class _CodegenState {
''';
}
String _genLastInDirective(ProtoRecord r) {
String _maybeGenLastInDirective(ProtoRecord r) {
if (!r.lastInDirective) return '';
return '''
${_genNotifyOnChanges(r)}
$_CHANGES_LOCAL = null;
${_genNotifyOnPushDetectors(r)}
$_IS_CHANGED_LOCAL = false;
''';
}
String _genNotifyOnChanges(ProtoRecord r) {
String _genOnCheck(ProtoRecord r) {
var br = r.bindingRecord;
if (!r.lastInDirective || !br.callOnChange()) return '';
return '''
if($_CHANGES_LOCAL) {
${_genGetDirective(br.directiveRecord.directiveIndex)}
.onChange($_CHANGES_LOCAL);
$_CHANGES_LOCAL = null;
}
''';
return 'if (!throwOnChange) '
'${_genGetDirective(br.directiveRecord.directiveIndex)}.onCheck();';
}
String _genOnInit(ProtoRecord r) {
var br = r.bindingRecord;
return 'if (!throwOnChange && !$_ALREADY_CHECKED_ACCESSOR) '
'${_genGetDirective(br.directiveRecord.directiveIndex)}.onInit();';
}
String _genOnChange(ProtoRecord r) {
var br = r.bindingRecord;
return 'if (!throwOnChange && $_CHANGES_LOCAL != null) '
'${_genGetDirective(br.directiveRecord.directiveIndex)}'
'.onChange($_CHANGES_LOCAL);';
}
String _genNotifyOnPushDetectors(ProtoRecord r) {
@ -447,6 +474,7 @@ class _CodegenState {
const PROTO_CHANGE_DETECTOR_FACTORY_METHOD = 'newProtoChangeDetector';
const _ALREADY_CHECKED_ACCESSOR = '_alreadyChecked';
const _BASE_CLASS = '$_GEN_PREFIX.AbstractChangeDetector';
const _CHANGES_LOCAL = 'changes';
const _CONTEXT_ACCESSOR = '_context';

View File

@ -27,6 +27,7 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
final _gen.List<_gen.ProtoRecord> _protos;
final _gen.List<_gen.DirectiveRecord> _directiveRecords;
dynamic _locals = null;
dynamic _alreadyChecked = false;
MyComponent _context = null;
_MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry,
@ -44,6 +45,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
var changes = null;
context = _context;
_alreadyChecked = true;
}
void callOnAllChangesDone() {}
@ -52,6 +55,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
mode = 'ALWAYS_CHECK';
_context = context;
_locals = locals;
_alreadyChecked = false;
}
void dehydrate() {