Consider the following case.
@Component({
template: `
<button (click)="noop()">Trigger change detection</button>
<div>{{increment('componentView')}}</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
class App {
increment() {
counters++;
}
noop() {}
}
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
expect(counters).toEqual(2); // current behavior is 1
The reason is App is a OnPush component with a hostView, calling fixture.detectChanges() will run a detectChanges() and checkNoChanges() .
And the App component is onPush, so the checkNoChanges() run will ignore App component, so the counters will be 1
Which is not correct.
Another case is:
it('works', () => {
@Component({
template: '{{message}}',
changeDetection: ChangeDetectionStrategy.OnPush
})
class OnPushCmp {
@Input() message = 'initial';
ngAfterViewInit() {
this.message = 'updated';
}
}
const comp = TestBed.configureTestingModule({declarations: [OnPushCmp]}).createComponent(OnPushCmp);
expect(() => comp.detectChanges()).toThrow(); // current behavior is not throw.
});
The reason is the same, the checkNoChanges() will skip the OnPushCmp, so the ExpressionChanged error is not thrown.
Consider the following case.
The reason is App is a OnPush component with a hostView, calling fixture.detectChanges() will run a detectChanges() and checkNoChanges() .
And the App component is onPush, so the checkNoChanges() run will ignore App component, so the counters will be 1
Which is not correct.
Another case is:
The reason is the same, the
checkNoChanges()will skip theOnPushCmp, so theExpressionChangederror is not thrown.