angular2/rxjs ng Отписаться: как отписаться от всех подписок с декоратором?
На основании edit3 здесь я реализовал это решение. Но сделать эту инициализацию субъекта и "очистить" в ngOnDestroy в каждом компоненте - все еще боль. Я думал, что это может быть передано декоратору, например. основываясь на этом посте:
export function AutoUnsubscribe( constructor ) {
const original = constructor.prototype.ngOnDestroy;
constructor.prototype.ngUnsubscribe = new Subject<void>();
constructor.prototype.ngOnDestroy = function () {
constructor.prototype.ngUnsubscribe.next();
constructor.prototype.ngUnsubscribe.complete();
original && typeof original === "function" && original.apply(this, arguments);
};
}
Использование, как и любой другой класс декоратор. И это хорошо работает, но мне пришлось взломать систему типов при ее использовании, вот так: takeUntil((this as any).ngUnsubscribe)
,
Свойство ngUnsubscribe не распознается системой типов в компоненте. Есть ли способ сообщить системе типов, что это свойство есть или будет?
Если это было бы возможно, тогда было бы очень легко использовать этот декоратор @AutoUnsubscribe: просто украсьте класс и поместите takeUntil(this.ngUnsubscribe) перед каждой подпиской. Интересно, можем ли мы сделать еще лучше, просто украсив класс, и автоматически этот декоратор поместит takeUntil(this.ngUnsubscribe) перед каждой подпиской на нас.
Мой текущий обходной путь - использовать BaseComponent с подпрограммой ngUnsubscribe. и расширить каждый компонент, который вызывает подписку.
1 ответ
Может быть, я собираюсь использовать слишком модельный пример, но я думаю, что есть два способа сделать это:
Создайте интерфейс, который просто сообщает компилятору о свойстве класса
Расширьте модуль, соответствующий вашему имени файла, и добавьте свойство в интерфейс.
1. Создайте интерфейс
export interface MyOtherClass {
magicProperty: string;
}
export class MyOtherClass
{
func(): void {
console.log(this.magicProperty);
}
}
2. Расширить модуль
// 43479078.ts
export class MyOtherClass
{
func(): void {
console.log(this.magicProperty);
}
}
...а также
// MyOtherClass-extension.d.ts
import { MyOtherClass } from './43479078';
declare module './43479078' {
interface MyOtherClass {
magicProperty: void;
}
}
Просто знайте, что теперь при компиляции вам нужно будет включить оба файла или добавить /// <reference path="./MyOtherClass-extension.d.ts" />
на вершине 43479078.ts
,
Кроме того, я думаю, что расширенный класс необходимо экспортировать, потому что в противном случае файл не будет считаться модулем.