franco
franco

Reputation: 697

Angular: Re-enable automatic change detection

I took over development of an Angular app from a collegue that already had things configured. One of those things is OnPush change detection. It seems that all the components are configured to have it. I changed one of my component's change detection strategy to Default but it still wouldn't detect any changes unless I call detectChange().

Where in my application should I change to revert automatic change detection?

Upvotes: 0

Views: 545

Answers (2)

Poul Kruijt
Poul Kruijt

Reputation: 71961

There are two different things. You have manual change detection, in which you have the application provide the NoopNgZone as zone. This will disable all change detection. If this is the case, all you need to do is remove the ngZone: 'noop' setting:

platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: 'noop' }) // remove noop

If this is not the case, then I suppose you mean the OnPush ChangeDetectionStrategy, defined in the Component decorator. This only works if all the parents of the child also have their strategy set to Default.

However, I strongly advice you to keep it on OnPush, this will make your application faster, easier to test, and predictable. You won't have to deal with 'expression was changed after check' errors (almost never). The component is checked when an @Input value changed, or when an event happened from within the component.

You are better of rewriting your code, perhaps by utilizing the async pipe, to reduce the usage of .detectChanges() and .markForCheck()


For instance if you want a clock, you can do it like this:

readonly clock$: Observable<Date> = interval(1000).pipe(  
  map(() => Date.now()),
  startWith(Date.now())
);

And in your template:

<div>{{ clock$ | async | date:'medium' }}</div>

This will update your template every second to the current time and date.

That's the beauty of the async pipe. You don't have to subscribe and unsubscribe. This is all handled in the pipe. Under the hood, the async pipe also calls the change detection for that component on every emit. By saying that, make sure you put this 'clock' in a dedicated component, with a small template. This way the change detection will only run for that clock element, so you don't have any performance issues with the local change detection being run every second

Upvotes: 1

tilo
tilo

Reputation: 14169

I assume that you mean the OnPush change detection strategy by "manual change detection". The strategy is inherited from parent components, i.e., you would need to change those in order to revert to the default change detection strategy.

However, before doing so: do you really need the default change detection strategy (thinking of performance, ..)? When in doubt: there is a good read on change detection strategies.

Upvotes: 1

Related Questions