Angular2:是否使用自定义装饰器或注释将提供程序注入组件?

杰森·德雷泽纳(Jason Dreyzehner)

@Page使用简单的方法在Ionic 2中隐藏某些标签(Ionic 2装饰器)TabsProvider

tabs.ts

import { Injectable } from 'angular2/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class TabsProvider {
  currentState = new BehaviorSubject<boolean>(true);
  public showTabs(){
    this.currentState.next(true);
  }
  public hideTabs(){
    this.currentState.next(false);
  }
}

tabs组件订阅currentState,并TabsProvider注入到以下各个页面中:

sample-page.ts

import {Page} from 'ionic-angular';
import { TabsProvider } from './tabs';

@Page({
  ...
})
export class SamplePage {
  tabsProvider: TabsProvider;

  constructor(tabsProvider: TabsProvider) {
    this.tabsProvider = tabsProvider;
  }

  onPageWillEnter(){
    this.tabsProvider.hideTabs();
  }

  onPageWillLeave(){
    this.tabsProvider.showTabs();
  }
}

该代码实际上是所有样板代码,如果我可以在装饰器(或注解)中定义此功能,则它会更加简洁,例如:

import { Page } from 'ionic-angular';
import { hideTabs } from './tabs';

@hideTabs()
@Page({
  ...
})
export class BuyPage {
}

但是我在确定如何注入TabsProvider以及将onPageWillEnteronPageWillLeave方法添加到SamplePage时遇到了麻烦

装饰器(或注释)可以以某种方式注入其他Angular提供程序吗?

到目前为止,我走得最远:

tabs.ts

export function hideTabs() {
  return function(cls: any) {
    cls.prototype.onPageWillEnter = function() {
      this.tabsProvider.hideTabs();
    };
    cls.prototype.onPageWillLeave = function() {
      this.tabsProvider.showTabs();
    };
    return cls;
  }
}

这使我们成为了我们所需要的一部分,但是仍然有必要TabsProvider作为特定实例成员进行导入和注入

sample-page.ts

import {Page, Events} from 'ionic-angular';
import { hideTabs, TabsProvider } from './tabs';

@hideTabs()
@Page({
  ...
})
export class SamplePage {
  constructor(public tabsProvider: TabsProvider) {
  }
}

是否可以将其完全抽象为@hideTabs()

编辑:

选项卡组件的相关部分(适用于有兴趣实施的人员)pages/tabs/tabs.ts

import { Page } from 'ionic-angular';
import { TabsProvider } from './tabs';

@Page({
  ...
})
export class TabsPage {

  ...

  currentState: boolean;
  constructor(TabsProvider: TabsProvider) {
    TabsProvider.currentState.subscribe((state: boolean) => {
      this.currentState = state;
    });
  }
}

pages/tabs/tabs.html

<div [ngClass]="{'hide-tabs': !currentState}">
  <ion-tabs>
    ...
  </ion-tabs>
</div>

pages/tabs/tabs.scss

.hide-tabs ion-tabbar-section {
    display: none;
}
尼科·伯恩斯

我遇到了同样的问题,这是我想出的解决方案。通用方法是:

  • 用于Reflect.getOwnMetadata从类中读取现有的依赖项。
  • 添加到依赖项列表
  • 创建一个新的构造函数,该构造函数包装旧的构造函数并处理这些依赖项。

tabs.ts

    import TabsProvider from "./tabs";

    export function hideTabs() {
      return function(cls: Function) : any {

        // Save existing onPageWillEnter and onPageWillLeave inplementations
        let enter = cls.prototype.onPageWillEnter || function () {};
        let leave = cls.prototype.onPageWillLeave || function () {};

        // Create new constructor for class
        const newCls = function (tabsProvider, ...args) {
            this.__hideTabs__tabsProvider = tabsProvider;
            return cls.apply(this, args);
        }

        // Copy prototype to new constructor
        newCls.prototype = constructor.prototype;

        // Copy metadata to new constructor
        let metadatakeys = Reflect.getMetadataKeys(cls);
        metadatakeys.forEach(function (key) {
          Reflect.defineMetadata(key, Reflect.getOwnMetadata(key, cls), newCls)
        });

        // Read dependencies list from 'cls', add our own dependency, and write list to 'newCls'
        let dependencies = Reflect.getOwnMetadata('design:paramtypes', cls);
        dependencies = [TabsProvider].concat(dependencies)
        Reflect.defineMetadata('design:paramtypes', params, newCls);

        // Define new onPageWillEnter and onPageWillLeave implementation which implement tab show/hide functionality
        // and also call the old implementation saved above (if they exist)
        newCls.prototype.onPageWillEnter = function() {
          this.tabsProvider.hideTabs();
          enter.apply(this, arguments);
        };

        newCls.prototype.onPageWillLeave = function() {
          this.tabsProvider.showTabs();
          leave.apply(this, arguments);
        };

        return newCls;
      }
    }

我也建议移动@hideTabs下面的装饰@Page装饰

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Angular2中的自定义异常处理程序

Angular2的自定义渲染器

在Angular2的自定义验证器中注入服务

将自定义组件与Angular2结合使用时,JQueryUI Sortable不起作用

Angular 2如何将自定义提供程序注入服务?

Angular 2-自定义注释

Angular2 FormBuilder:在自定义验证器中使用“ this”

Angular2注入的自定义服务未定义

Angular 5:在自定义装饰器函数内部使用服务

Angular 6 ProvidedIn-如何自定义@Injectable()提供程序以进行依赖项注入?

使用自定义TS装饰器的组件方法未定义Angular服务

是否可以在不使用NPM的情况下使用自定义的TestCafé浏览器提供程序?

Angular 7:自定义类装饰器销毁组件范围

如何将依赖项注入与自定义装饰器集成

Angular 2自定义装饰器取消订阅策略

如何将html元素注入自定义组件

如何使自定义装饰器对vue.js 2应用程序全局可用?

为动态创建的外部+ AOT编译组件提供自定义注入器

确保使用自定义装饰器装饰金字塔应用程序中的每个视图

如何使用Jasmine(Angular JS)对自定义装饰器进行单元测试

angular2中的装饰器在组件中做什么?

Angular2中的自定义值访问器

Angular2自定义验证器未调用

Angular2:在组件视图中通过ngIf使用自定义时间

Angular 2自定义装饰器(适用于RC4之后的版本)提供了“多个组件”

在angular2的自定义Http中未定义注入的Logger

如何使用 Simple Injector 将类注入到我的自定义模型绑定器提供程序中?

Angular2 是否提供使用注入器注册的项目的命名空间?

有没有办法将范围服务注入自定义控制器激活器(或页面模型激活器提供程序)?