2016-09-09 6 views
0

TL; DRУгловые 2: «Глобальные» крючки жизненного цикла?

Мы строим приложение с угловыми 2 и хотели бы зарегистрировать «глобальный» ngOnInit и ngOnDestroy функцию. С «глобальным» я подразумеваю, что функция выполняется для каждого компонента, без необходимости явно реализовывать для каждого компонента. Это возможно?

Подробное

Некоторые (но не все) наши компоненты должны зарегистрировать что-то в глобальной службы, когда они загружены (например, ngOnInit) и разрегистрировать его снова после того, как они разгружаются (например ngOnDestroy). Вот два подхода я могу думать:

  • Реализовать эту логику в каждом компоненте, который нужно сделать (в ngOnInit и ngOnDestroy).
  • Реализовать эту логику в базовом классе, который вызывает абстрактные методы, реализуемые подклассами, которые определяют, что необходимо зарегистрировать/незарегистрировать.

Оба подхода не очень удовлетворительный:

  • В первом мне нужно снова и снова реализовать всю логику. Да, я знаю, я мог бы поставить код «котел» в классе помощника или что-то в этом роде. Но он кажется слегка скрытым, «скрытым» в регулярном углеродном жизненном цикле. Наличие говорящего имени (например, интерфейса/базового класса) представляется более явным.
  • Во втором классе все классы должны расширять один и тот же общий базовый класс. Но что, если они также должны расширить какой-либо другой базовый класс (множественное наследование)?

Вот почему я придумал следующую мысль:

Почему бы не заменить упомянутый выше абстрактный класс с интерфейсом, который может быть реализован всеми необходимыми компонентами. Затем я бы зарегистрировал глобальную функцию, которая выполняется на всех ngOnInit и ngOnDestroy всех компонентов (если это возможно - например, в модуле, маршрутизации и т. Д.?). В функции я бы проверил, реализует ли компонент интерфейс, и если да, то вызовите соответствующую функцию, чтобы получить материал типа, который нужно зарегистрировать.

Мои вопросы

  • Может УГЛОВОЕ 2 сделать это? То есть может ли быть зарегистрирован «глобальный крючок жизненного цикла» (или что-то в этом роде)?
  • Или это абсолютно неправильный подход?
  • Любые другие/лучшие идеи?

ответ

5

Принудительное поведение для всего приложения не будет хорошей идеей, это скажется и на сторонних компонентах для стартеров.

Код котельной можно переместить в базовый класс бетона. Существуют решения для множественного наследования JS/TS, например. @mixin, см. Также TypeScript guide.

Поскольку методы базового класса являются фиксированными, класс Mixin может быть выражен в виде упрощенной декоратора:

class CustomLifecycle implements OnInit, OnDestroy { 
    constructor(
    public originalNgOnInit: Function, 
    public originalNgOnDestroy: Function 
) {} 

    ngOnInit() { 
    ... 
    if (typeof this.originalNgOnInit === 'function') { 
     this.originalNgOnInit(); 
    } 
    } 

    ngOnDestroy() { 
    ... 
    if (typeof this.originalNgOnDestroy === 'function') { 
     this.originalNgOnDestroy(); 
    } 
    } 
} 

function Lifecycled() { 
    return function (target: Function) { 
    const customLifecycle = new CustomLifecycle(
     target.prototype.ngOnInit, 
     target.prototype.ngOnDestroy 
    ); 

    target.prototype.ngOnInit = customLifecycle.ngOnInit; 
    target.prototype.ngOnDestroy = customLifecycle.ngOnDestroy; 
    } 
} 

И он может быть использован как

@Component({ ... }) 
@Lifecycled() 
class SomeComponent { .... } 

Реализация ограничена до ngOnInit и т.д. прототипов, члены стрелки требуют, чтобы конструктор был исправлен.

Смежные вопросы