2

我有一个在组件的 HTML 部分中使用的自定义管道。它在模块中声明:

  declarations: [  I18nPipe ],

我希望能够从组件代码(而不是transform方法)中调用它的方法。

我希望管道实例存在于依赖注入上下文中的某个位置,以便我可以抓住它。但是我错了。如果我将它注入到组件的构造函数中(例如任何普通服务):

  constructor(private i18nPipe: I18nPipe)  

然后我得到一个错误:没有提供者。所以我将它包含在providers同一模块的部分中:

  providers: [ I18nPipe ]

然后我将可以在组件代码中访问它,但我的自定义管道会有两个实例。

  1. 创建者providers,在 DI 上下文中可用。在构造函数中注入时我会得到这个实例,所以我将在我的组件代码中使用这个实例。

  2. HTML 中使用的实例。它在哪里生活?我想在我的组件代码中访问这个实例,而不是“提供”的那个;我怎样才能获得它?

4

1 回答 1

6

每个 Angular 组件都被编译到带有节点的视图中。管道是节点类型之一。除了父组件和在组件的宿主元素上定义的指令之外,您不能注入视图节点。

假设您有以下组件模板:

<div>{{3|mypipe}}</div>

您将拥有以下视图节点:

PipeElement
HTMLDivElement
HTMLTextElement

然后在变更检测期间,Angular 会遍历每个节点并执行变更检测特定的操作——dom 更新、绑定更新或transform方法调用。

如果需要,您可以通过 View 实例(不是公共 API)访问管道实例,如下所示:

class I18nPipe {
   sayHello() {}
}

class ComponentWithPipe {

  constructor(cd: ChangeDetectorRef) {
    setTimeout(() => {
      const pipeNode = cd._view.nodes.find((n) => {
        return n.instance && n.instance instanceof I18nPipe
      });
      const pipeInstance = pipeNode.instance;
      pipeInstance.sayHello();
    })
  }

但这仅用于教育目的。您不想在生产中使用这种方法。

以下是一些有助于您理解的文章:

于 2017-08-31T05:33:32.007 回答