Build Errors
一般的な間違い
デコレーターにて丸括弧を忘れる
デコレーターはアノテーションの後に丸括弧 ()
を持つべきです。いくつか例を示します: @Injectable()
, @Optional()
, @Input()
, など。
@Directive({
selector: 'my-dir',
})
class MyDirective {
// 誤り、@Optional() とすべき
// @Optional はここでは何もしないため、MyDirective は parent が undefined の場合にエラーになる
constructor(@Optional parent: ParentComponent) {}
}
一般的なエラー
すべてのパラメータを解決できない
Cannot resolve all parameters for 'YourClass'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'YourClass' is decorated with Injectable.
この例外は Angular が YourClass
のコンストラクタの 1 つ以上のパラメータについて困惑していることを意味します。依存性を注入 するため、Angular は 注入するパラメータの型を知る必要があります。パラメータのクラスを指定することで Angular にこのこと(タイプ)を知らせます。次の点を確認してください:
- パラメータのクラスをインポートします。
- パラメータに適切な注釈をつけるか、パラメータの型を指定します。
import { MyService } from 'my-service'; // 私をインポートすることを忘れないで!
@Component({
template: `Hello World`,
})
export class MyClass {
// service は MyService のタイプです
constructor(service: MyService) {}
}
コード内の循環参照がこのエラーの原因になることがあります。循環参照は、2 つのオブジェクトが相互に依存していることを意味するため、両方を相互の前に宣言する方法はありません。この問題を回避するには、Angular に組み込まれているforwardRef
関数を使用します。
import { forwardRef } from '@angular/core';
@Component({
selector: 'my-button',
template: `<div>
<icon></icon>
<input type="button" />
</div>`,
directives: [forwardRef(() => MyIcon)], // MyIcon はま だ定義されていません
}) // forwardRef は MyIcon が必要なときに MyIcon として解決します
class MyButton {
constructor() {}
}
@Directive({
selector: 'icon',
})
class MyIcon {
constructor(containerButton: MyButton) {} // MyButton が定義されました
}
No provider for ParamType
No provider for ParamType! (MyClass -> ParamType)
これは、Angular は注入されるべきパラメータの型を知っているが、注入方法を知らないことを意味する。
パラメータが Service の場合は、指定したクラスがアプリケーションで使用可能な providers のリストに追加されていることを確認します:
import { MyService } from 'my-service';
@Component({
templateUrl: 'app/app.html',
providers: [MyService], // 私を忘れないで!
})
class MyApp {}
パラメータが別のコンポーネントまたは Directive (たとえば、親コンポーネント)である場合、パラメータを providers のリストに追加するとエラーはなくなりますが、これは前述の provider の複数のインスタンス と同じ効果を持ちます。ここでは、コンポーネントクラスの新しいインスタンスを作成しますが、必要なコンポーネントインスタンスへの参照は取得しません。かわりに、注入されるであろう Directive またはコンポーネントがコンポーネントで使用可能であることを確認します(たとえば、親であることを期待している場合は、実際に親であること)。これはおそらく、例を使用すると最も簡単に理解できます:
@Component({
selector: 'my-comp',
template: '<p my-dir></p>',
directives: [forwardRef(() => MyDir)],
})
class MyComp {
constructor() {
this.name = 'My Component';
}
}
@Directive({
selector: '[my-dir]',
})
class MyDir {
constructor(c: MyComp) {
// <-- This is the line of interest
// コンポーネントツリーにMyCompがなく、注入するMyCompがないため、
// Directiveが通常のdivにある場合のエラーのdivにある場合のエラー
console.log("Host component's name: " + c.name);
}
}
@Component({
template:
'<my-comp></my-comp>' + // MyDir コンストラクタ内ではエラーなし、MyComp は MyDir の親
'<my-comp my-dir></my-comp>' + // MyDir コンストラクタ内ではエラーなし、MyComp は MyDir のホスト
'<div my-dir></div>', // MyDir コンストラクタ内でエラー
directives: [MyComp, MyDir],
})
class MyApp {}
以下に、使用可能な注入するものの図を示します:
+-------+
| App |
+---+---+
|
+-------------+------------+
| |
+------+------+ +--------+--------+
| Div (MyDir) | | MyComp (MyDir) | <- MyComp は注入可能
+-------------+ +--------+--------+
^ |
MyComp の注入なし +------+------+
| P (MyDir) | <- MyComp は親から注入可能
+-------------+
前の例を拡張するために、コンポーネント/Directive の参照を常に期待しているわけではない場合には、Angular の @Option
アノテーションを使うことができます:
@Directive({
selector: '[my-dir]',
})
class MyDir {
constructor(@Optional() c: MyComp) {
// No longer errors if c is undefined
if (c) {
console.log(`Host component's name: ${c.name}`);
}
}
}
既知のプロパティではないため、propertyName
にバインドできない
Can't bind to 'propertyName' since it isn't a known property of the 'elementName' element and there are no matching directives with a corresponding property
これは、そのプロパティを持たない要素にプロパティをバインドしようとしたときに発生します。要素がコンポーネントの場合、または要素に 1 つ以上の Directive がある場合、コンポーネントも Directive もそのプロパティを持ちません。
<!-- div には 'foo' というプロパティがない -->
<div [foo]="bar"></div>
ControlContainer の Provider がない
No provider for ControlContainer! (NgControlName -> ControlContainer)
このエラーは、上記の No provider
エラーのより具体的なバージョンです。これは、親の NgForm または NgFormModel を指定せずに NgControlName などのフォームコントロールを使用した場合に発生します。ほとんどの場合、これはフォームコントロールが実際のフォーム要素内にあることを確認することで解決できます。NgForm はセレクタとして form
を使用するので、これは新しい NgForm をインスタンス化します:
@Component({
template:
'<form>' +
'<input ngControl="login">' +
'</form>'
})
コンポーネントファクトリがない
No component factory found for <component name>
このエラーは、ngModule にインポートおよび追加されていない Component、Provider Pipe、Directive を使用しようとしたときに発生します。新しい Component、Provider、Pipe、Directive をアプリケーションに追加する場合は必ず、Angular がそれを使えるように するために、src/app/app.module.ts
ファイル内の ngModule
に追加する必要があります。このエラーを修正するには、問題の Component、Provider、Pipe、Directive を app.module ファイルにインポートし、Provider の場合は providers
配列に追加、Component、Pipe、Directive の場合は宣言配列と entryComponents
配列の両方に追加します。