Angular 2とFirebaseを使用して簡単なブログを作成しようとしていますが、コンポーネントで非同期パイプを使用すると問題が発生します。コンソールにエラーが表示されます。
zone.js:344未処理のプロミス拒否:テンプレート解析エラー:パイプ「非同期」が見つかりませんでした( "
[エラー->] {{(blog.user | async)?. first_name}}
"):BlogComponent @ 6:3;ゾーン:;タスク:Promise.then;値:エラー:テンプレート解析エラー:(…)エラー:テンプレート解析エラー:パイプ 'async'が見つかりません("
blog.component.ts
import {Component, Input} from "@angular/core";
@Component({
selector: 'blog-component',
templateUrl: './blog.component.html',
styleUrls: ['./blog.component.css'],
})
export class BlogComponent {
@Input() blog;
}
blog.component.html
<h1 class="article-title">{{ blog.title }}</h1>
<p>{{ (blog.user | async)?.first_name }}</p>
app.component.ts
import { Component } from '@angular/core';
import { BlogService } from "./services/services.module";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private blogService: BlogService) {}
articles = this.blogService.getAllArticles();
}
app.component.html
<article *ngFor="let article of articles | async">
<blog-component [blog]="article"></blog-component>
</article>
blog.service.ts
import {Injectable} from "@angular/core";
import {AngularFire} from "angularfire2";
import {Observable} from "rxjs";
import "rxjs/add/operator/map";
@Injectable()
export class BlogService {
constructor(private af: AngularFire) { }
getAllArticles(): Observable<any[]> {
return this.af.database.list('articles', {
query: {
orderByKey: true,
limitToLast: 10
}
}).map((articles) => {
return articles.map((article) => {
article.user = this.af.database.object(`/users/${article.user_id}`);
return article;
});
});
}
}
この問題は、blog.component.htmlファイルで非同期を使用しようとしたときにのみ発生します。 app.component.htmlファイルでユーザー名を印刷しようとすると機能します。 blog.module.tsにAsyncPipeを注入する必要がありますか? blog.component.tsで非同期を機能させるにはどうすればよいですか?
@NgModule.declarations
は、子モジュールに継承されません。パイプ、ディレクティブ、モジュールのコンポーネントが必要な場合、モジュールを機能モジュールにインポートする必要があります。
すべてのコアパイプを含むモジュールは、@angular/common
からのCommonModule
です。
import { CommonModule } from '@angular/common';
@NgModule({
imports: [ CommonModule ]
})
class BlogModule {}
app.component
で機能する理由は、BrowserModule
をAppModule
にインポートする可能性が高いためです。 BrowserModule
はCommonModule
を再エクスポートするため、BrowserModule
をインポートすることは、CommonModule
もインポートするようなものです。
CommonModule
には、ngFor
やngIf
などのコアディレクティブも含まれていることにも注意してください。したがって、それらを使用する機能モジュールがある場合は、CommonModule
もそのモジュールにインポートする必要があります。
Angular 6または7にアップグレードした場合、tsconfig.tsでenableIvyをオフにしてくださいangularCompilerOptions
例えば:
angularCompilerOptions: {
enableIvy : false; // default is true
}
これで私の問題は解決しました。誰かの時間も節約できるかもしれません。
App.module.tsで複数のモジュールを使用している場合も、同じエラーが発生する可能性があります
import { MatCardModule } from '@angular/material';
import { AppComponent } from './app.component';
// module 1
@NgModule({ exports: [MatCardModule] })
export class MaterialModule {}
// module 2
@NgModule({
imports: [MaterialModule]
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
次に、コマンドを使用してコンポーネントを生成する場合:
ng generate component example
2番目のモジュールではなく、最初のモジュールに追加されます。
import { MatCardModule } from '@angular/material';
import { AppComponent } from './app.component';
import { ExampleComponent } from './example/example.component';
// module 1
@NgModule({ exports: [MatCardModule], declarations: [ExampleComponent] })
export class MaterialModule {}
// module 2
@NgModule({
imports: [MaterialModule]
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
同じエラーが発生します!コンポーネントをAppModuleに移動すると修正されます。
@NgModule({
imports: [MaterialModule]
declarations: [AppComponent, ExampleComponent],
bootstrap: [AppComponent]
})
export class AppModule {}