【问题标题】:Angular Pipe not working on child routesAngular Pipe 不适用于子路由
【发布时间】:2018-11-11 08:54:45
【问题描述】:

我在 Angular 5 中有一个非常简单的管道

import { Pipe, Injectable } from '@angular/core';

@Pipe({
    name: "default"
})
@Injectable()
export class DefaultPipe {
    transform(value: string, fallback: string): string {
        let image = "";
        if (value) {
            image = value;
        } else {
            image = fallback;
        }
        return image;
    }
}

我以非常简单的方式使用它只是为了演示

<div>
    {{ 'somthing' | default }}
</div> 

我还在 app.module.ts 的 provider 部分添加了

@NgModule({
    declarations: [
        AppComponent,
        DefaultPipe // <-- Here
    ],
    imports: [
        ....
    ],
    providers: [
        ....
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

当你在普通组件中使用它时,例如

app.component.html

它工作正常,但如果你在子路由中使用的组件中使用它,则会出现此错误:

compiler.js:486 未捕获错误:模板解析错误:管道 找不到“默认”(“

{{[错误 ->] '东西' |默认 }} "): ng:///AppRoutingModule/LoginComponent.html@75:6 在 syntaxError (compiler.js:486) 在 TemplateParser.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.TemplateParser.parse (compiler.js:24674) 在 JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._parseTemplate (compiler.js:34629) 在 JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileTemplate (compiler.js:34604) 在 compiler.js:34505 在 Set.forEach() 在 JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileComponents (compiler.js:34505) 在 compiler.js:34375 在 Object.then (compiler.js:475) 在 JitCompiler.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:34374)

解决:

我将此模块添加为 share.module.ts

import { NgModule } from '@angular/core';
import { DefaultPipe } from './core/pipes/default.pipe';

@NgModule({
    declarations: [DefaultPipe],
    exports: [DefaultPipe]
})
export class SharedModule { }

并在 2 个地方使用它,一个在 app.module.ts

@NgModule({
declarations: [
    AppComponent,
],
imports: [
    ...
    // other modules
    ...
    SharedModule
],
providers: [
    ....
],
bootstrap: [AppComponent]

}) 导出类 AppModule { }

一个在 route.module.ts

@NgModule({
    declarations: [
        ....
    ],
    imports: [
        ....
        SharedModule
    ],
    exports: [
        RouterModule,
    ]
})

export class AppRoutingModule { }

【问题讨论】:

  • 能否请您添加声明LoginComponent 的模块?
  • 为什么要投反对票?你付出了所有的努力来解决一个有很多解释的问题,然后你去,你得到了一个投票,非常感谢!!!

标签: angular typescript angular-pipe


【解决方案1】:

你不需要在管道上使用 Injectable 装饰器,所以你可以删除它。

此外,正如其他答案中已经建议的那样,我建议您明确实现 PipeTransform 接口以与管道 API 保持一致。

compiler.js:486 Uncaught Error: Template parse errors: The pipe 'default' could not be found ("

{{[错误 ->] '东西' |默认 }} "): ng:///AppRoutingModule/LoginComponent.html@75:6 at syntaxError (compiler.js:486)

基本上是说您的管道既没有在模块中声明也没有导入,其中声明了LoginComponent

最简单和最干净的解决方案是在新的 NgModule 类中声明/导出管道,然后您可以将其导入每个声明使用管道的组件的模块中。例如:

@NgModule({
  declarations: [DefaultPipe],
  exports: [DefaultPipe]
})
export class DefaultPipeModule{}

@NgModule({
  imports: [DefaultPipeModule],
  declarations: [LoginComponent]
})
export class FooModule {}

@NgModule({
  imports: [DefaultPipeModule],
  declarations: [FooComponent] // fooComponent also uses the default pipe, so we need to import its module
})
export class SomeOtherModule{}

【讨论】:

  • 我不知道他们为什么不给你一票,但你的建议实际上是正确的,它确实解决了我的问题。我添加了一个共享模块并在我的路由模块和应用程序模块中使用它并且它有效。谢谢
  • @EhsanZargarErshadi 您介意在评论您的问题时添加我要求的信息吗?只是为了确保您的问题可以帮助其他人
【解决方案2】:

参考:here

自定义管道:

首先,没有 @Injectable() 因为它不是您将在构造函数中定义的服务。 然后,需要导入'@angular/core'中提供的PipeTransform并实现。

例子:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: "default"
})

export class DefaultPipe implements PipeTransform {
    transform(value: string, fallback: string): string {
        let image = "";
        if (value) {
            image = value;
        } else {
            image = fallback;
        }
        return image;
    }
}

【讨论】:

    【解决方案3】:

    创建辅助组件、管道或指令的最佳做法是创建一个SharedModule 并将其放入其中。

    组件、指令和管道不像服务那样​​工作。您可以将它注入到 AppModule 的服务数组中的服务,它也适用于儿童。

    管道、指令或组件,您必须在 NgModule 中声明它们,然后将其导入您需要的地方,因为它们只能属于 1 个模块(但是该模块可以根据需要多次导入!)

    因此,您可以做的最好的事情是创建一个 SharedModule 并使用以下内容:

    @NgModule({
      imports: [ ... ],
      declarations: [ DefaultPipe ],
      exports: [ DefaultPipe ]
    })
    export class SharedModule { }
    

    然后在AppModule 中导入SharedModule,如下所示:

    imports: [ SharedModule ]
    

    现在,如果您想在 LoginComponent 或应用程序的任何其他部分中使用它,您可以在该组件的模块中导入您的 SharedModule

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 1970-01-01
      相关资源
      最近更新 更多