-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use the new inject function #198
Comments
Hey, I’ll reply a bit later, I’m onto phone for next the week. |
Sure, take your time. |
Considering the above example, how the operator will be used for non-component classes? Services, NgModules, pipes, etc (since they all may implement the OnDestroy interface)? |
It should work the same. |
@Injectable()
export class BarService {
destroy$ = untilDestroyed();
init() {
interval(1000).pipe(
this.destroy$
).subscribe(console.log)
}
} @Component({
selector: 'app-foo',
templateUrl: './foo.component.html',
providers: [
BarService
],
}) |
There're some cases I've noticed where it doesn't work compared to the existing behavior: @NgModule()
export class SomeModule {
destroy$ = untilDestroyed(); // No provider for ChangeDetectorRef!
}
@Injectable({ providedIn: 'root' })
export class RootService {
destroy$ = untilDestroyed(); // No provider for ChangeDetectorRef!
} Embedded views: @Pipe({ name: 'impure', pure: false })
export class ImpurePipe implements PipeTransform {
destroy$ = untilDestroyed();
constructor() {
new Subject()
.pipe(
this.destroy$,
finalize(() => console.log('Finalized')) // Not called
)
.subscribe();
}
transform(value: string) {
return 'Hey';
}
ngOnDestroy(): void {
console.log('Called when `shown` becomes `false`.');
}
}
@Directive({ selector: '[myDirective]' })
export class MyDirective {
destroy$ = untilDestroyed();
constructor() {
new Subject()
.pipe(
this.destroy$,
finalize(() => console.log('Finalized')) // Not called
)
.subscribe();
}
ngOnDestroy(): void {
console.log('Called when `shown` becomes `false`.');
}
}
@Component({
selector: 'app-root',
template: `
<button (click)="shown = !shown">Toggle</button>
<ng-template [ngIf]="shown">
<div myDirective></div>
{{ "" | impure }}
</ng-template>
`
})
export class AppComponent {
shown = true;
} |
|
Actually, it makes sense because we are injecting ChangeDetectorRef. |
Hmm what about doing something like this (quick pseudo code): const symbol = Symbol('untilDestroyed');
const patched = Symbol('patched');
export function untilDestroyed(instance: any) {
const proto = Object.getPrototypeOf(instance);
if (!proto[patched]) {
proto[patched] = true;
const original = proto.ngOnDestroy;
proto.ngOnDestroy = function () {
original?.apply(this, arguments);
this[symbol].next();
this[symbol].complete();
}
}
instance[symbol] = new Subject<void>();
return takeUntil(instance[symbol].asObservable())
} |
This code works, but I don't see any benefit over our current approach. I'm closing the issue for now. |
Since Angular 14 was released, as I mentioned in my previous blog post, we can now create something like:
Should we remove the decorator approach or provide both solutions? @arturovt
The text was updated successfully, but these errors were encountered: