fix(change_detection): update the right change detector when using ON_PUSH mode
Previously, in a case where you have a mix of ON_PUSH and DEFAULT detectors, Angular would update the status of a wrong detector.
This commit is contained in:
@@ -210,6 +210,10 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected getDetectorFor(directives: any, index: number): ChangeDetector {
|
||||
return directives.getDetectorFor(this.directiveRecords[index].directiveIndex);
|
||||
}
|
||||
|
||||
protected notifyDispatcher(value: any): void {
|
||||
this.dispatcher.notifyOnBinding(this._currentBinding(), value);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ export class ChangeDetectorJITGenerator {
|
||||
|
||||
_maybeGenHydrateDirectives(): string {
|
||||
var hydrateDirectivesCode = this._genHydrateDirectives();
|
||||
var hydrateDetectorsCode = this._genHydrateDetectors();
|
||||
var hydrateDetectorsCode = this._logic.genHydrateDetectors(this.directiveRecords);
|
||||
if (!hydrateDirectivesCode && !hydrateDetectorsCode) return '';
|
||||
return `${this._typeName}.prototype.hydrateDirectives = function(directives) {
|
||||
${hydrateDirectivesCode}
|
||||
@@ -161,16 +161,6 @@ export class ChangeDetectorJITGenerator {
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
_genHydrateDetectors(): string {
|
||||
var detectorFieldNames = this._names.getAllDetectorNames();
|
||||
var lines = ListWrapper.createFixedSize(detectorFieldNames.length);
|
||||
for (var i = 0, iLen = detectorFieldNames.length; i < iLen; ++i) {
|
||||
lines[i] = `${detectorFieldNames[i]} = directives.getDetectorFor(
|
||||
${this._names.getDirectivesAccessorName()}[${i}].directiveIndex);`;
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
_maybeGenCallOnAllChangesDone(): string {
|
||||
var notifications = [];
|
||||
var dirs = this.directiveRecords;
|
||||
|
||||
@@ -3,6 +3,7 @@ import {BaseException, Json, StringWrapper} from 'angular2/src/facade/lang';
|
||||
import {CodegenNameUtil} from './codegen_name_util';
|
||||
import {codify, combineGeneratedStrings, rawString} from './codegen_facade';
|
||||
import {ProtoRecord, RecordType} from './proto_record';
|
||||
import {DirectiveRecord} from './directive_record';
|
||||
|
||||
/**
|
||||
* This is an experimental feature. Works only in Dart.
|
||||
@@ -131,4 +132,16 @@ export class CodegenLogicUtil {
|
||||
iVals.push(codify(protoRec.fixedArgs[protoRec.args.length]));
|
||||
return combineGeneratedStrings(iVals);
|
||||
}
|
||||
|
||||
genHydrateDetectors(directiveRecords: DirectiveRecord[]): string {
|
||||
var res = [];
|
||||
for (var i = 0; i < directiveRecords.length; ++i) {
|
||||
var r = directiveRecords[i];
|
||||
if (!r.isDefaultChangeDetection()) {
|
||||
res.push(
|
||||
`${this._names.getDetectorName(r.directiveIndex)} = this.getDetectorFor(directives, ${i});`);
|
||||
}
|
||||
}
|
||||
return res.join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,11 +200,5 @@ export class CodegenNameUtil {
|
||||
return this._addFieldPrefix(`directive_${d.name}`);
|
||||
}
|
||||
|
||||
getAllDetectorNames(): List<string> {
|
||||
return ListWrapper.map(
|
||||
ListWrapper.filter(this.directiveRecords, r => !r.isDefaultChangeDetection()),
|
||||
(d) => this.getDetectorName(d.directiveIndex));
|
||||
}
|
||||
|
||||
getDetectorName(d: DirectiveIndex): string { return this._addFieldPrefix(`detector_${d.name}`); }
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ class _CodegenState {
|
||||
|
||||
String _maybeGenHydrateDirectives() {
|
||||
var hydrateDirectivesCode = _genHydrateDirectives();
|
||||
var hydrateDetectorsCode = _genHydrateDetectors();
|
||||
var hydrateDetectorsCode = _logic.genHydrateDetectors(_directiveRecords);
|
||||
if (hydrateDirectivesCode.isEmpty && hydrateDetectorsCode.isEmpty) {
|
||||
return '';
|
||||
}
|
||||
@@ -244,16 +244,6 @@ class _CodegenState {
|
||||
return '$buf';
|
||||
}
|
||||
|
||||
String _genHydrateDetectors() {
|
||||
var buf = new StringBuffer();
|
||||
var detectorFieldNames = _names.getAllDetectorNames();
|
||||
for (var i = 0; i < detectorFieldNames.length; ++i) {
|
||||
buf.writeln('${detectorFieldNames[i]} = directives.getDetectorFor('
|
||||
'${_names.getDirectivesAccessorName()}[$i].directiveIndex);');
|
||||
}
|
||||
return '$buf';
|
||||
}
|
||||
|
||||
/// Generates calls to `onAllChangesDone` for all `Directive`s that request
|
||||
/// them.
|
||||
String _maybeGenCallOnAllChangesDone() {
|
||||
|
||||
Reference in New Issue
Block a user