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,

Кроме того, я думаю, что расширенный класс необходимо экспортировать, потому что в противном случае файл не будет считаться модулем.

Другие вопросы по тегам