fix(NgClass): throw a descriptive error when CSS class is not a string (#12662)
Fixes #12586
This commit is contained in:
parent
22c021c57f
commit
f3793b5953
|
@ -9,7 +9,7 @@
|
||||||
import {CollectionChangeRecord, Directive, DoCheck, ElementRef, Input, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, Renderer} from '@angular/core';
|
import {CollectionChangeRecord, Directive, DoCheck, ElementRef, Input, IterableDiffer, IterableDiffers, KeyValueChangeRecord, KeyValueDiffer, KeyValueDiffers, Renderer} from '@angular/core';
|
||||||
|
|
||||||
import {isListLikeIterable} from '../facade/collection';
|
import {isListLikeIterable} from '../facade/collection';
|
||||||
import {isPresent} from '../facade/lang';
|
import {isPresent, stringify} from '../facade/lang';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngModule CommonModule
|
* @ngModule CommonModule
|
||||||
|
@ -108,8 +108,14 @@ export class NgClass implements DoCheck {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _applyIterableChanges(changes: any): void {
|
private _applyIterableChanges(changes: any): void {
|
||||||
changes.forEachAddedItem(
|
changes.forEachAddedItem((record: CollectionChangeRecord) => {
|
||||||
(record: CollectionChangeRecord) => this._toggleClass(record.item, true));
|
if (typeof record.item === 'string') {
|
||||||
|
this._toggleClass(record.item, true);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`NgClass can only toggle CSS classes expressed as strings, got ${stringify(record.item)}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
changes.forEachRemovedItem(
|
changes.forEachRemovedItem(
|
||||||
(record: CollectionChangeRecord) => this._toggleClass(record.item, false));
|
(record: CollectionChangeRecord) => this._toggleClass(record.item, false));
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
|
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
|
||||||
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('binding to CSS class list', () => {
|
describe('binding to CSS class list', () => {
|
||||||
|
@ -187,6 +186,13 @@ export function main() {
|
||||||
getComponent().arrExpr = ['foo bar baz foobar'];
|
getComponent().arrExpr = ['foo bar baz foobar'];
|
||||||
detectChangesAndExpectClassName('foo bar baz foobar');
|
detectChangesAndExpectClassName('foo bar baz foobar');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should throw with descriptive error message when CSS class is not a string', () => {
|
||||||
|
fixture = createTestComponent(`<div [ngClass]="['foo', {}]"></div>`);
|
||||||
|
expect(() => fixture.detectChanges())
|
||||||
|
.toThrowError(
|
||||||
|
/NgClass can only toggle CSS classes expressed as strings, got \[object Object\]/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('expressions evaluating to sets', () => {
|
describe('expressions evaluating to sets', () => {
|
||||||
|
@ -348,4 +354,4 @@ class TestComponent {
|
||||||
function createTestComponent(template: string): ComponentFixture<TestComponent> {
|
function createTestComponent(template: string): ComponentFixture<TestComponent> {
|
||||||
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
|
return TestBed.overrideComponent(TestComponent, {set: {template: template}})
|
||||||
.createComponent(TestComponent);
|
.createComponent(TestComponent);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue