What is a dehydrated detector and how am I using o

2020-03-01 07:28发布

问题:

I'm using a simple directive to focus a text input when the element is active using *ngIf. This is contained within a *ngFor loop.

When the first *ngIf is activated, the input focuses as expected. When another input is activated I get the error:

EXCEPTION: Attempt to use a dehydrated detector.

I don't understand what this means and how I can prevent the error. The functionality still works even with the error.

@Directive({
    selector: '[myAutoFocus]'
})
export class AutoFocusDirective {
    constructor(private elem: ElementRef) {
        window.setTimeout(function() {
            elem.nativeElement.querySelector('input').focus();
        });
    }
}

```

回答1:

Dehydrated detector is a component that has been removed from the change detection system, usually because it has been unmounted from DOM by *ngIf or other means: If there's an asynchronous action in the application that hits this already unmounted detector, error is thrown: solution is to use [hidden] instead of *ngIf on the affected component, or defer the offending action to next tick using setTimeout( () => this.offendingAction(), 0)



回答2:

There is an open issue on GitHub for this: https://github.com/angular/angular/issues/6786#issuecomment-185429140

In beta.2, no exception was thrown. In beta.3-6 (4,5, and 6 seem to be just increments with no changes), the code was changed to throw an exception. You are correct that this currently does not pose an issue.

While I do not know the exact reason you receive this error, one of my accounts with it came from disposing of a component during the angular check cycle, where it updates views. Others have logged their issues on the github thread.



回答3:

A "dehydrated detector" means that the change detector for that component/directive is no longer hydrated. (Sorry, I just couldn't resist -- I have no idea what this error means either, nor do I know what "hydrated" or "dehydrated" is supposed to convey.)

This source file says:

/**
 * Thrown when change detector executes on dehydrated view.
 *
 * This error indicates a bug in the framework.
 *
 * This is an internal Angular error.
 */
export class DehydratedException extends BaseException {
  constructor(details: string) { super(`Attempt to use a dehydrated detector: ${details}`); }
}

So you probably found an internal Angular bug.

I can't reproduce your error with this simple plunker. Do you have a plunker that shows the issue?

See also https://github.com/angular/angular/issues/6786



回答4:

I have had this exception before and it very much means that you are using something that is no longer exists in the virtual memory. In my case, I was doing almost the same what you were doing. Notice you are trying to access an element after a timeout, but are you sure this element exists in the memory after this time is elapsed? I have *ngIf on that element and I accessed after the condition was false and it was already removed.



标签: angular