diff --git a/packages/common/src/directives/ng_class.ts b/packages/common/src/directives/ng_class.ts index cd4bd6bfeb..1eae99666f 100644 --- a/packages/common/src/directives/ng_class.ts +++ b/packages/common/src/directives/ng_class.ts @@ -49,15 +49,16 @@ export class NgClass implements DoCheck { @Input('class') set klass(v: string) { - this._applyInitialClasses(true); + this._removeClasses(this._initialClasses); this._initialClasses = typeof v === 'string' ? v.split(/\s+/) : []; - this._applyInitialClasses(false); - this._applyClasses(this._rawClass, false); + this._applyClasses(this._initialClasses); + this._applyClasses(this._rawClass); } @Input() set ngClass(v: string|string[]|Set|{[klass: string]: any}) { - this._cleanupClasses(this._rawClass); + this._removeClasses(this._rawClass); + this._applyClasses(this._initialClasses); this._iterableDiffer = null; this._keyValueDiffer = null; @@ -87,11 +88,6 @@ export class NgClass implements DoCheck { } } - private _cleanupClasses(rawClassVal: string[]|{[klass: string]: any}): void { - this._applyClasses(rawClassVal, true); - this._applyInitialClasses(false); - } - private _applyKeyValueChanges(changes: KeyValueChanges): void { changes.forEachAddedItem((record) => this._toggleClass(record.key, record.currentValue)); changes.forEachChangedItem((record) => this._toggleClass(record.key, record.currentValue)); @@ -115,19 +111,34 @@ export class NgClass implements DoCheck { changes.forEachRemovedItem((record) => this._toggleClass(record.item, false)); } - private _applyInitialClasses(isCleanup: boolean) { - this._initialClasses.forEach(klass => this._toggleClass(klass, !isCleanup)); - } - - private _applyClasses( - rawClassVal: string[]|Set|{[klass: string]: any}, isCleanup: boolean) { + /** + * Applies a collection of CSS classes to the DOM element. + * + * For argument of type Set and Array CSS class names contained in those collections are always + * added. + * For argument of type Map CSS class name in the map's key is toggled based on the value (added + * for truthy and removed for falsy). + */ + private _applyClasses(rawClassVal: string[]|Set|{[klass: string]: any}) { if (rawClassVal) { if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) { - (rawClassVal).forEach((klass: string) => this._toggleClass(klass, !isCleanup)); + (rawClassVal).forEach((klass: string) => this._toggleClass(klass, true)); } else { - Object.keys(rawClassVal).forEach(klass => { - this._toggleClass(klass, isCleanup ? false : !!rawClassVal[klass]); - }); + Object.keys(rawClassVal).forEach(klass => this._toggleClass(klass, !!rawClassVal[klass])); + } + } + } + + /** + * Removes a collection of CSS classes from the DOM element. This is mostly useful for cleanup + * purposes. + */ + private _removeClasses(rawClassVal: string[]|Set|{[klass: string]: any}) { + if (rawClassVal) { + if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) { + (rawClassVal).forEach((klass: string) => this._toggleClass(klass, false)); + } else { + Object.keys(rawClassVal).forEach(klass => this._toggleClass(klass, false)); } } }