fix(change_detect): Sort DirectiveMetadata properties during processing

The Angular 2 render compiler can get out of sync between its transformer
execution and its runtime execution, leading to incorrect change detectors with
out-of-order property values. Stable sorting solves this problem (temporarily).
This commit is contained in:
Tim Blasi
2015-07-20 13:37:50 -07:00
parent 4c8ea12903
commit b2a0be87e8
6 changed files with 33 additions and 9 deletions

View File

@ -76,17 +76,17 @@ export class DirectiveParser implements CompileStep {
});
}
if (isPresent(dirMetadata.hostListeners)) {
MapWrapper.forEach(dirMetadata.hostListeners, (action, eventName) => {
this._sortedKeysForEach(dirMetadata.hostListeners, (action, eventName) => {
this._bindDirectiveEvent(eventName, action, current, directiveBinderBuilder);
});
}
if (isPresent(dirMetadata.hostProperties)) {
MapWrapper.forEach(dirMetadata.hostProperties, (expression, hostPropertyName) => {
this._sortedKeysForEach(dirMetadata.hostProperties, (expression, hostPropertyName) => {
this._bindHostProperty(hostPropertyName, expression, current, directiveBinderBuilder);
});
}
if (isPresent(dirMetadata.hostAttributes)) {
MapWrapper.forEach(dirMetadata.hostAttributes, (hostAttrValue, hostAttrName) => {
this._sortedKeysForEach(dirMetadata.hostAttributes, (hostAttrValue, hostAttrName) => {
this._addHostAttribute(hostAttrName, hostAttrValue, current);
});
}
@ -97,6 +97,16 @@ export class DirectiveParser implements CompileStep {
});
}
_sortedKeysForEach(map: Map<string, string>, fn: (value: string, key: string) => void): void {
var keys = MapWrapper.keys(map);
ListWrapper.sort(keys, (a, b) => {
// Ensure a stable sort.
var compareVal = StringWrapper.compare(a, b);
return compareVal == 0 ? -1 : compareVal;
});
ListWrapper.forEach(keys, (key) => { fn(MapWrapper.get(map, key), key); });
}
_ensureHasOnlyOneComponent(elementBinder: ElementBinderBuilder, elDescription: string): void {
if (isPresent(elementBinder.componentId)) {
throw new BaseException(